548

IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Embed Size (px)

Citation preview

Page 1: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008
Page 2: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

WIN

REGISTER YOUR BOOKibmpressbooks.com/ibmregister

REGISTRATION ENTITLES YOU TO:• Supplemental materials that may be available• Advance notice of forthcoming editions• A coupon that can be used on your next purchase from ibmpressbooks.com

IBM PRESS NEWSLETTERSign up for the monthly IBM PRESS NEWSLETTER at

ibmpressbooks.com/newsletters

LEARN

• NEW PODCASTSfrom your favorite authors

• ARTICLES & INTERVIEWSwith authors

• SPECIAL OFFERSfrom IBM Press and partners

• NOTICES & REMINDERS about author appearances and conferences

Visit ibmpressbooks.com for all product information

Sign up for the IBM PRESS NEWSLETTER and you will be automatically entered into a

QUARTERLY GIVE-AWAY for 3 months access to Safari Books Online –

online access to more than 5000 booksA $150 VALUE!

Sign up at ibmpressbooks.com/newsletter

Page 3: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Service-Oriented Architecture (SOA) Compass Business Value, Planning, and Enterprise Roadmapby Norbert Bieberstein, Sanjay Bose, Marc Fiammante, Keith Jones, and Rawn ShahISBN: 0-13-187002-5

In this book, IBM® Enterprise Integration Team experts present a start-to-fi nish guide to plan-ning, implementing, and managing Service-Oriented Architecture. Drawing on their extensive experience helping enterprise customers migrate to SOA, the authors share hard-earned lessons and best practices for architects, project manag-ers, and software development leaders alike.

Well-written and practical, Service-Oriented Architecture Compass offers the perfect blend of principles and “how-to” guidance for transitioning your infrastructure to SOA. The authors clearly explain what SOA is, the opportunities it offers, and how it differs from earlier approaches. Using detailed examples from IBM consulting engage-ments, they show how to deploy SOA solutions that tightly integrate with your processes and operations, delivering maximum fl exibility and value. With detailed coverage of topics ranging from policy-based management to workfl ow implementation, no other SOA book offers comparable value to workingIT professionals.

WebSphere Business Integration Primer Process Server, BPEL, SCA, and SOAby Ashok Iyengar, Vinod Jessani, and Michele ChilantiISBN: 0-13-224831-X

Using WebSphere® Business Integration (WBI) technology, you can build an enterprise-wide Business Integration (BI) infrastructure that makes it easier to connect any business resources and functions, so you can adapt more quickly to the demands of customers and partners. Now there’s an introductory guide to creating standards-based process and data integration solutions with WBI.

WebSphere Business Integration Primerthoroughly explains Service Component Architecture (SCA), basic business processes, and complex long-running business fl ows, and guides you to choose the right process integration architecture for your requirements. Next, it intro-duces the key components of a WBI solution and shows how to make them work together rapidly and effi ciently. This book will help developers, technical professionals, or managers understand today’s key BI issues and technologies, and streamline business processes by combining BI with Service Oriented Architecture (SOA).

Related Books of Interest

Sign up for the monthly IBM Press newsletter at ibmpressbooks/newsletters

Page 4: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Related Books of Interest

Visit ibmpressbooks.com for all product information

The New Language of BusinessSOA & Web 2.0by Sandy CarterISBN: 0-13-195654-X

In The New Language of Business, senior IBM executive Sandy Carter demonstrates how to leverage SOA, Web 2.0, and related technologies to drive new levels of operational excellence and business innovation.

Writing for executives and business leaders inside and outside IT, Carter explains why fl exibility and responsiveness are now even more crucial to success — and why services-based strategies offer the greatest promise for achieving them.

You’ll learn how to organize your business into reusable process components — and support them with cost-effective IT services that adapt quickly and easily to change. Then, using extensive examples — including a detailed case study describing IBM’s own experience — Carter identifi es best practices, pitfalls, and practical starting points for success.

Listen to the author’s podcast at:ibmpressbooks.com/podcasts

Executing SOAA Practical Guide for the Service-Oriented Architectby Norbert Bieberstein, Robert G. Laird, Dr. Keith Jones, and Tilak MitraISBN: 0-13-235374-1

In Executing SOA, four experienced SOA implementers share realistic, proven, “from-the-trenches” guidance for successfully delivering on even the largest and most complex SOA initiative.

This book follows up where the authors’ best-selling Service-Oriented Architecture Compassleft off, showing how to overcome key obstacles to successful SOA implementation and identifying best practices for all facets of execution—technical, organizational, and human. Among the issues it addresses: introducing a services discipline that supports collaboration and information process sharing; integrating services with preexisting technology assets and strategies; choosing the right roles for new tools; shifting culture, governance, and architecture; and bringing greater agility to the entire organizational lifecycle, not just isolated projects.

Listen to the author’s podcast at:ibmpressbooks.com/podcasts

Page 5: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Related Books of Interest

Sign up for the monthly IBM Press newsletter at ibmpressbooks/newsletters

Enterprise Java Programming with IBM WebSphereSecond Editionby Kyle Brown, Dr. Gary Craig, Greg Hester, David Pitt, Russell Stinehour, Mark Weitzel, Jim Amsden, Peter M. Jakab, and Daniel Berg ISBN: 0-321-18579-X

Enterprise Java™ Programming with IBM WebSphere, Second Edition is the defi nitive guide to building mission-critical enterprise systems with J2EE™, WebSphere, and WebSphere Studio Application Developer. Fully updated for Versions 5.x of WebSphere Application Server and WebSphere Studio Application Developer, it combines expert architectural best practices with a case study that walks you through constructing an entire system.

The authors are an extraordinary team of WebSphere insiders: developers, consultants, instructors, and IBM WebSphere development team members. Together, they offer unprec-edented insight into the use and behavior of WebSphere’s APIs in real-world environments — and systematic guidance for delivering systems of exceptional performance, robustness, and business value.

IBM WebSphere and LotusLamb, Laskey, IndurkhyaISBN: 0-13-144330-5

Enterprise Messaging Using JMS and IBM WebSphereYusufISBN: 0-13-146863-4

IBM WebSphere System AdministrationWilliamson, Chan, Cundiff, Lauzon, Mitchell ISBN: 0-13-144604-5

Outside-in Software DevelopmentKessler, Sweitzer ISBN: 0-13-157551-1

Enterprise Master Data ManagementDreibelbis, Hechler, Milman, Oberhofer, van Run, Wolfson ISBN: 0-13-236625-8

Page 6: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Rapid PortletDevelopmentwith WebSphere®

Portlet Factory

RequirementsRequirements

Page 7: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 8: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

IBM WebSphere

[SUBTITLE ]

Deployment and AdvancedConfiguration

Roland Barcia, Bill Hines, Tom Alcott, and Keys Botzum

Rapid PortletDevelopment withWebSphere®

Portlet Factory

Step-by-Step Guide for BuildingYour Own Portlets

David Bowley

IBM PressPearson plcUpper Saddle River, NJ • Boston • Indianapolis • San FranciscoNew York • Toronto • Montreal • London • Munich • Paris • MadridCape Town • Sydney • Tokyo • Singapore • Mexico City

Ibmpressbooks.com

Page 9: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The author and publisher have taken care in the preparation of this book, but make no expressed or impliedwarranty of any kind and assume no responsibility for errors or omissions. No liability is assumed forincidental or consequential damages in connection with or arising out of the use of the information orprograms contained herein.

© Copyright 2009 by International Business Machines Corporation. All rights reserved.

Note to U.S. Government Users: Documentation related to restricted right. Use, duplication, or disclosureis subject to restrictions set forth in GSA ADP Schedule Contract with IBM Corporation.

IBM Press Program Managers: Tara Woodman, Ellice UfferCover Design: IBM Corporation

Associate Publisher: Greg WiegandMarketing Manager: Kourtnaye SturgeonPublicist: Heather FoxAcquisitions Editor: Katherine BullDevelopment Editor: Kevin HowardManaging Editor: Kristy HartDesigner: Alan ClementsSenior Project Editor: Lori LyonsCopy Editor: Deadline Driven PublishingIndexer: WordWise Publishing ServicesCompositor: Nonie RatcliffProofreader: Water Crest PublishingManufacturing Buyer: Dan Uhrig

Published by Pearson plc

Publishing as IBM Press

IBM Press offers excellent discounts on this book when ordered in quantity for bulk purchases or specialsales, which may include electronic versions and/or custom covers and content particular to your business,training goals, marketing focus, and branding interests. For more information, please contact:

U. S. Corporate and Government [email protected]

For sales outside the U.S., please contact:

International [email protected]

Page 10: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The following terms are trademarks or registered trademarks of International Business MachinesCorporation in the United States, other countries, or both: IBM, the IBM logo, IBM Press, DB2, Domino,Domino Designer, Lotus, Lotus Notes, Rational, and WebSphere. Java and all Java-based trademarks aretrademarks of Sun Microsystems, Inc. in the United States, other countries, or both. Microsoft, Windows,Windows NT, and the Windows logo are trademarks of the Microsoft Corporation in the United States,other countries, or both. Linux is a registered trademark of Linus Torvalds. Intel, Intel Inside (logo), MMX,and Pentium are trademarks of Intel Corporation in the United States, other countries, or both. Othercompany, product, or service names may be trademarks or service marks of others.

Library of Congress Cataloging-in-Publication Data

Bowley, David.Rapid portlet development with WebSphere portlet factory : step-by-step guide for building your own

portlets / David Bowley.p. cm.

Includes index.ISBN 0-13-713446-0 (hardback : alk. paper) 1. Web portals—Computer programs. 2. User interfaces

(Computer systems) Computer programs. 3. Web site development. 4. WebSphere. I. Title. TK5105.8885.W43B69 2008

006.7’6—dc222008029014

All rights reserved. This publication is protected by copyright, and permission must be obtained from thepublisher prior to any prohibited reproduction, storage in a retrieval system, or transmission in any form orby any means, electronic, mechanical, photocopying, recording, or likewise. For information regardingpermissions, write to:

Pearson Education, IncRights and Contracts Department501 Boylston Street, Suite 900Boston, MA 02116Fax (617) 671 3447

ISBN-13: 978-0-13-713446-5ISBN-10: 0-13-713446-0

Text printed in the United States on recycled paper at R.R. Donnelley in Crawfordsville, Indiana.First printing September 2008

Page 11: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 12: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

xi

Contents at a Glance

Foreword xxvii

Preface xxix

Acknowledgments xxxiii

About the Author xxxv

Chapter 1 Introduction to WebSphere Portlet Factory 1

Chapter 2 Providing and Consuming Services 37

Chapter 3 Using Data from a Relational Data Source 53

Chapter 4 Using Domino Data 77

Chapter 5 Customizing Portlet Appearance 107

Chapter 6 Adding Basic User Interface Controls to Your Portlets 149

Chapter 7 Communicating Between Portlets 165

Chapter 8 Using Java in Portlets 195

Chapter 9 Using Web Services and Manipulating XML 239

Chapter 10 Using Charts in Portlets 267

Chapter 11 Field Validation, Formatting, and Translation 293

Chapter 12 Profiling Portlets 323

Chapter 13 Using Ajax and Dojo 345

Chapter 14 Error Handling, Logging, and Debugging Portlets 371

Chapter 15 Performance and Process Optimization 393

Chapter 16 More Techniques for Domino 413

Appendix A Setting Up your Environment 439

Appendix B Portlet Factory Properties 461

Glossary 475

Index 493

Page 13: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 14: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

xiii

Contents

Foreword xxvii

Preface xxix

Acknowledgments xxxiii

About the Author xxxv

Chapter 1 Introduction to WebSphere Portlet Factory 1What Is a Portal and What Are Portlets? 2Portal Key Benefits 3What Is WPF? 4WPF Key Benefits 4WPF Architecture 5

Builders 5Models 6Profiles 7Generating and Executing the WebApp 7Portlet Factory WAR Files 11Deployment Configurations 12

Introduction to the WebSphere Portlet Factory Designer 13The User Interface 13Folder Structure 17

Building Your First Portlet 21Creating a Project 21Manual Deployment 26Creating a Model 30Testing the Application 31

Summary 35Important Points 35

Page 15: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Chapter 2 Providing and Consuming Services 37The Service Provider/Consumer Pattern 37Creating a Service Provider 39

Creating a Model 40Defining the Service 41Adding Roster Data 42Adding an Action to Retrieve a Roster 43Adding a Service Operation 43

Testing the Service Provider 44Creating a Service Consumer 45

Creating a Model 46Configuring the Portlet Adapter 47Testing the Service Consumer 47

Creating a Stub Service 48Applying the Service Provider/Consumer Pattern 49Summary 51Important Points 51

Chapter 3 Using Data from a Relational Data Source 53Using Data Services 53Creating a Service Provider 54

Creating a Model 54Defining the Service 55Specifying the First Operation 55Specifying the Second Operation 55Specifying the Third Operation 56Specifying the Fourth Operation 57Specifying the Fifth Operation 58

Testing the Service Provider 60Testing the retrieveContactsView Operation 61Testing the getContactDetail Operation 62Testing the createContact Operation 63Testing the setContact Operation 63Testing the deleteContact Operation 63

Creating a Contacts Portlet 63Creating a Model 64Configuring the Portlet Adapter 65Adding Update Functionality 65Adding Delete Functionality 66Adding Create Functionality 69Testing the Contacts Portlet 72

Summary 74Important Points 75

xiv Contents

Page 16: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Chapter 4 Using Domino Data 77Portalizing Notes Functionality 78Configuring Your Environment 79

Configuring the Domino Properties File 80Testing the Connection to Domino 81

Creating a Service Provider 82Creating a Model 82Defining the Service 83Specifying Operations 83Adding a Delete Operation 85

Testing the Service Provider 88Testing the readSupplierView Operation 88Testing the readSupplierDocument Operation 89Testing the updateSupplierDocument Operation 90Testing the createSupplierDocument Operation 90Testing the deleteSupplierDocument Operation 90

Creating a Suppliers Portlet 91Creating a Model 91Configuring the Portlet Adapter 93Adding Update Functionality 94Adding Delete Functionality 94Adding Create Functionality 97Removing Unwanted Fields 99

Testing the Service Consumer 100Using a Stub Service 102

Creating a Stub Model 103Using the Stub Model 104

Summary 105Important Points 105

Chapter 5 Customizing Portlet Appearance 107Customizing Portlet Appearance 108Creating a Service Provider 108

Creating a Model 109Defining the Service 109Adding an Asset Schema 109Adding Asset Data 110Adding an Action to Retrieve a List of Assets 112Specifying the getAssetsList Operation 112

Testing the Service Provider 113Creating an Assets Portlet 114

Creating a Model 114Adding a Portlet Adapter 114

Contents xv

Page 17: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Consuming the Service 114Displaying Assets Data 114Testing the Assets Portlet 117

Pagination 119Turning on Pagination 120Modifying the Paging Buttons 120

Data Modifiers 122The Data Column Modifier Builder 122The Data Hierarchy Modifier Builder 124The Data Field Modifier Builder 124The Form Layout Builder 127

Working with Web Pages 132HTML Builders 133JSP Builders 135JavaScript 135HTML Templates 137

Cascading Style Sheets 142Adding a Style Sheet 144

Summary 146Important Points 146

Chapter 6 Adding Basic User Interface Controlsto Your Portlets 149

User Interface Controls in WPF 149Creating a Survey Portlet 151

Creating a Model 151Modifying the Page 152Adding a Portlet Adapter 153

Testing the Survey Portlet 160Summary 163Important Points 164

Chapter 7 Communicating Between Portlets 165The Benefits of Inter-Portlet Communication 166The WebSphere Property Broker 166Creating a Service Provider 167

Creating a Model 168Defining the Service 168Adding Loan Data 168Adding an Action to Retrieve a List of Loans 169Specifying the getLoansList Operation 170Adding a Method to Retrieve a Specific Loan 170Specifying the getLoanDetail Operation 171

xvi Contents

Page 18: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the Service Provider 171Creating a List Portlet 173

Creating a Model 173Specifying the Service 173Specifying List and Detail Operations 174Configuring the Portlet Adapter 175Defining the Portlet as a Cooperative Source 176Testing the List Portlet 177

Creating a Detail Portlet 177Creating a Model 178Adding a Default Message Page 179Adding a main Action 179Adding an Interface for Loan Details 179Defining the Portlet as a Cooperative Target 180Handling an Inter-Portlet Communication Event 181Testing the Detail Portlet 182

Configuring the WebSphere Property Broker 183Testing Inter-Portlet Communication 184

Alternative Communication Methods 184Property Broker Action 185WPF Event Model 186Shared Variables 189Configuring Actions for loansList 191Running selectLoan 192Using the Shared Variable in the loanDetail Model 192Click-to-Action (C2A) 192

When to Use Inter-Portlet Communication 192Summary 193Important Points 193

Chapter 8 Using Java in Portlets 195Java Development Considerations 196Java Methods 198

Inline Java 198Action Lists 200The Method Builder 200The Linked Java Object Builder 201

Java Application Programming Interfaces 202com.bowstreet.WebApp.WebAppAccess 203com.bowstreet.webapp.Variables 206com.bowstreet.webapp.RequestInputs 207com.bowstreet.util.IXml and com.bowstreet.util.XmlUtil 208javax.servlet.http.HttpServletRequest and javax.servlet.http.HttpServletResponse 209

Contents xvii

Page 19: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Java Beans 210Creating a Java Bean and Bean Manager 210

Creating a Shopping Cart Item Bean 211Creating a Shopping Cart Item Manager 213

Creating a Service Provider 216Creating a Model 217Defining the Service 217Adding a Linked Java Object 217Adding a Java to XML Converter 217Clearing a Shopping Cart 218Viewing a Shopping Cart 219Viewing a Shopping Cart Item 221Adding a Shopping Cart Item 222Updating a Shopping Cart Item 223Deleting a Shopping Cart Item 223

Testing the Service Provider 224Testing the addShoppingCartItem Operation 225Testing the viewShoppingCart Operation 225Testing the viewShoppingCartItem Operation 225Testing the updateShoppingCartItem Operation 226Testing the deleteShoppingCartItem Operation 226Testing the clearShoppingCart Operation 226

Creating a Shopping Cart Portlet 226Creating a Model 226Configuring the Portlet Adapter 228Implementing the updateShoppingCartItem Operation 228Implementing the addShoppingCartItem Operation 229Implementing the clearShoppingCart Operation 229Implementing the deleteShoppingCartItem Operation 230Testing the Shopping Cart Portlet 232Testing the Add Item Button 232Testing the Edit Item Button 233Testing the Delete Item Button 233Testing the Clear Cart Button 233

Java Archives 234Importing JARs 234Excluding JARs from WAR Files 235

Summary 236Important Points 236

xviii Contents

Page 20: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Chapter 9 Using Web Services and Manipulating XML 239Web Services in WPF 240Creating an Order Stock Web Service 242

Creating a Model 243Defining the Service 243Defining the Request Object 243Defining the Response Object 245Adding Order Data 246Adding a Method to Place a Stock Order 246Adding a Service Operation 251Testing the orderStockWebService Web Service 252

Creating a Service Provider 255Creating a Model and Defining the Service 255Calling the Web Service 256Adding a Service Operation 257Testing the Service Provider 258

Creating an Order Stock Portlet 258Creating a Model 259Modifying the Page 259Adding a Portlet Adapter 260Consuming the Service 260Creating a Variable to Store the Request 260Displaying the Interface 260Adding Submit Functionality 261Testing the Order Stock Portlet 262

XML Transform Builders 263Transform 263Transform - Filter 263Transform - Rename 264Transform - Sort 264

Summary 264Important Points 264

Chapter 10 Using Charts in Portlets 267Charting Data in WPF 268Creating a Service Provider 269

Creating a Model 269Defining the Service 270Adding Sales Data 270Adding a Sales Schema 271Adding an Action to Retrieve Sales Data 271Specifying the getSales Operation 271Testing the Service Provider 272

Contents xix

Page 21: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Sales Chart Portlet 273Creating a Model 273Modifying the Page 273Modifying the Main Action List 274Adding a Portlet Adapter 274Consuming the Service 275Adding a Chart 275Configuring the Data Transformation 276Specifying Chart Properties 277Specifying Minimum Scale Values 277Testing the Test Data Portlet 278

Adding Drill-Down Capabilities 279Adding Temporary Variables 280Defining the Transform 280Specifying a Method to Get the Current Sales Item 282Specifying an Action for the getSalesArea Operation 283Specifying the getSalesArea Operation 283Testing the getSalesArea Operation 284Adding a Page for the Sales Area Chart 284Adding an Action to Display the salesAreaPage 285Configuring the Click Action 285Populating the salesAreaPage Page 285Testing the Drill-Down from the salesChart Model 287

Custom Chart Styles 288Displaying TargetSales 289Using the Custom Style 290

Upgrading to a Deployment License 291Summary 292Important Points 292

Chapter 11 Field Validation, Formatting, and Translation 293Validating, Translating, and Formatting Fields 293

Schema Typed and Non-Schema Typed Fields 294Formatter Classes 295Client-Side and Server-Side Validation 295

Creating a Projects Portlet 296Creating a Model 296Modifying the Page 297Adding a Portlet Adapter 297Organizing Builders for page1 297Adding a Schema 298Adding a Variable to Hold User Input 299Modifying the Main Action List 299Creating a Form 299

xx Contents

Page 22: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Submit Button 299Adding a Confirmation Page 300Modifying the Submit Button 300Displaying the User’s Inputs 301Adding a Link to Return to the Project Form 301Running a Preliminary Test 302Adding Formatting, Validation, and Translation 303

Testing the Projects Portlet 309Writing a Formatter Class 312

Adding a Formatter Class 312The CustomFormatter Class 315Adding a Linked Java Object 316Adding a Data Field Modifier 316

Further Validation Customizations 316Adding a Resource Bundle 316Changing Messages for Regular Expressions 318Creating the Post-Save Action 318Modifying the Post-Save Action Code 319Running the Post-Save Action 321

Summary 321Important Points 322

Chapter 12 Profiling Portlets 323Profiling Builder Inputs 323Creating an Announcements Portlet 325

Creating a Model 326Modifying the Page 326Adding a Portlet Adapter 327Creating a Default Resource Bundle 327Creating a US English Resource Bundle 327Creating an ES Spanish Resource Bundle 328Localizing the Announcement Headings 328Profiling the Language Input 329Profiling the Country Input 332Setting a Selection Handler 332Placing Headings on the Page 334Adding English Announcements 335Adding Spanish Announcements 335Importing the Announcements 336Displaying the Announcements 336Running a Preliminary Test 337Testing the Selection Handler 338Profiling the hrHeader Based on Department 339Profiling the itHeader Based on Department 340

Contents xxi

Page 23: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Profiling the hrAnnouncements Based on Department 340Profiling the itAnnouncements Based on Department 340Configuring the userDepartment Profile Set 340Testing the companyAnnouncements Portlet 341

Summary 342Important Points 342

Chapter 13 Using Ajax and Dojo 345Using Ajax 345Creating a Service Provider 346

Creating a Model 347Defining the Service 347Adding Performance Data 347Adding Functionality for Retrieving Performance Data 348Specifying the getPerformanceData Operation 350Adding Functionality for Updating Performance Data 351Specifying the updatePerformanceData Operation 352

Testing the Service Provider 353Testing the getPerformanceData Operation 353

Creating a Performance Portlet 354Creating a Model 354Modifying the Page 355Adding a Portlet Adapter 355Consuming the Service 356Displaying the Interface 357Hiding and Showing a Column Using Ajax 357Responding to a Change in the Checkbox Value 358Adding an Area Select Field 359Adding Submit Functionality 359Adding Ajax Type Ahead 360

Testing the Performance Portlet 360Using Dojo 362

Enabling Dojo Capabilities 363Adding an Action to Save Comments 363Adding Inline Edit Capabilities 365Adding Tooltips 366Adding a Feedback Bar 367

Summary 369Important Points 369

Chapter 14 Error Handling, Logging, and Debugging Portlets 371Error Handling 371

Creating a Model 373Modifying the Results Page 374

xxii Contents

Page 24: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Division Variables 374Defining the Division Process 374Displaying the Result 375Running a Preliminary Test 375Creating a Custom Exception 376Throwing the Custom Exception 377Adding an Error Page 377Adding an Error Flag 378Adding an Error Action 379Adding an Error Handler 379Testing the Division Model 380

Debugging 380Debugging Statements 381Using Eclipse Debugging 382

Logging 385Debug Tracing 385Using a Custom Logging Category 388Server Stats 389

Summary 391Important Points 391

Chapter 15 Performance and Process Optimization 393Performance 393

Caching 394Data Set Size 395Builder Calls 395Session Size 395Profiling 398Using Ajax and Dojo 398

Custom Builders 399Creating a Model 400Modifying the Page 400Adding a Portlet Adapter 401Creating a Terms & Conditions Builder 401Defining Builder Inputs for the Custom Builder 403Generating the Custom Builder Artifacts 404Modifying the Custom Builder’s Functionality 405Modifying the Coordinator 407Using the Terms & Conditions Builder 407Testing the Information Model 408

Creating a New Model Wizard 409Testing the New Model Wizard Builder 410

Summary 411Important Points 411

Contents xxiii

Page 25: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Chapter 16 More Techniques for Domino 413Adding Common Notes Functionality 413

Notes Formulas, Validation, and Translation 414Notes Agents 419Keyword Lookups 424Categorized Views 428Hide-When Fields 433Rich Text 433Attachments 434

Domino Data Access Methods 434getDominoSession() and getDominoDatabase() 435setComputeWithFormEnabled(boolean) 435getUserName() 435sendDocument(IXml, boolean, boolean) and getDocumentData(String) 435

Summary 436Important Points 436

Appendix A Setting Up Your Environment 439Installing WebSphere Portlet Factory 439Configuring WebSphere Portal 441

Setting Up a New Target Page 441Setting Up Access 443

Configuring Lotus Domino 443Start the DIIOP and HTTP Tasks 444Enable HTTP Clients to Browse Databases 444

Creating a Test Database in DB2 446Creating a Test Database in SQL Server 448Configuring a JDBC Resource 451

Setting Up a DB2 Database Driver Provider 452Setting Up a SQL Server Driver Provider 453Configuring the Driver 453Configuring a DB2 Data Source 454Configuring a SQL Server Data Source 455Configuring an Authentication Mechanism 456Testing the Data Source 458

Appendix B Portlet Factory Properties 461Properties Files 461

bowstreet.properties, cluster.properties, and server.properties 462jdbcDrivers.properties, pageprocessors.properties, persistentstore.properties 462log4j.properties 462logging.properties 462migrate-profilesets.properties 462

xxiv Contents

Page 26: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Using Properties 464Domino Server Settings 465File Upload Settings 466Specifying an Alternate Compiler 466Dynamic Class Loading 466SOAP and Proxy Access for Web Services 467Avoiding Errors Caused by File Length Limitations 468The WPF Cache 468log4j Logging 469Debug Tracing 470Event Logging 471Server Statistics Logging 471Page Automation 472

Glossary 475

Index 493

Contents xxv

Page 27: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 28: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

xxvii

Foreword

Building good software applications is hard. Improvements in languages, frameworks, and toolsdo make things easier, and there are more of these improvements each year.

But at the same time, the technology landscape that developers live in keeps changing andgetting more complex. Just when you get productive with one set of tools and technology, there’ssomething new that you have to adapt to or integrate with. And there’s a perpetual demand for“more software quicker”—organizations can never get all the software they want as soon as theywant it.

WebSphere® Portlet Factory was created to apply concepts of software automation to helpaddress this ongoing problem of software development complexity. This software automationmoves the developer up a level, above the level of individual code artifacts. Instead of directlymanipulating elements such as JSP, Java™, JavaScript, and XML files, the developer interactswith builders in a model, and the builders then generate all the necessary code artifacts inresponse to the developer’s high-level instructions.

You can think of builders as encapsulations of software features or design patterns. Eachbuilder implements one feature of an application, controlled by instructions provided by thedeveloper in a wizard-like user interface. An application is built by successively adding and mod-ifying features (builders) until the application works as intended. The net effect for developers isthat they can rapidly develop complex applications without having to learn (and remember) allthe underlying technology.

In the past several years working with this technology, we’ve found that developers canconsistently get big productivity gains from this software automation. We’ve seen the technologyadopted by an ever-increasing customer base, first at Bowstreet (where the software was initiallydeveloped), and now at IBM, which acquired Bowstreet in late 2005. At IBM, the technology has

Page 29: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

also been adopted by a number of other product groups that build products on top of Portlet Fac-tory technology and take advantage of its software automation. For example, the Lotus®

ActiveInsight Dashboard Framework is built on Portlet Factory and provides a set of builders thatimplement high-level design patterns tailored for dashboard-style applications.

We’ve also found that automation makes it possible to quickly add support for new technol-ogy, such as integrating new back-end services or generating new user interface technologies.One example is support for Ajax (Asynchronous Java and XML) user interfaces. Implementingan Ajax user interface through hand-coding is quite complex and involves coordinated client-sidecode (JavaScript) and server-side code. Using builder technology, a small team with Ajax exper-tise was able to capture their expertise in a set of builders that automate common Ajax patternsand generate the necessary client and server code. Once the builders were created, those Ajax pat-terns became easily accessible to any developer using Portlet Factory.

In this book, David Bowley gives a clear “soup-to-nuts” guide to building applications withPortlet Factory, from creating your first project, to back-end integration, to user interface andAjax techniques. Each chapter tackles one aspect of application development, and for each taskDavid shows you which builders you need and how to use them. In his examples, I think you’llsee that David has found just the right level of complexity—the examples are simple enough toeasily understand, but not unrealistically simple or trivial.

Portlet Factory development—using builders and models instead of working directly withcode—represents a different development paradigm than with other tools. I hope you find asmuch value in this automation paradigm as we have. You can use this book as your guide as youlearn your way around Portlet Factory and get comfortable with this way of working.

Jonathan BoothSenior ArchitectWebSphere Portlet FactoryIBM

xxviii Foreword

Page 30: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

xxix

Preface

Portlet development can often be arduous and complicated; indeed, the word “rapid” is not nor-mally associated with building portlets. IBM’s award-winning1 WebSphere Portlet Factory(WPF), however, provides developers with a wizard-based development environment that greatlyexpedites the process of building, testing, and deploying portlets. WPF shields developers frommuch of the complexity of traditional portlet development, and portlets built using WPF oftenrequire little or no coding—enlarging the potential pool of people who are able to build portletapplications. Having said this, WPF developers also have the full power of Java 2 Enterprise Edi-tion (J2EE) available to them should they choose to use it, making WPF a flexible (and powerful)development tool.

This book is about how to use WPF to rapidly build portlets. No previous developmentexperience is required to understand this book, and anyone with a remote interest in portlet devel-opment should find something of interest here. The book is structured to facilitate rapid portletdevelopment: It is a collection of independent chapters, each walking through the process of cre-ating a portlet while focusing on a particular aspect of WPF. Due to the independent nature of thechapters (and the nature of portlet development using WPF), you can skip to the chapters thatinterest you without needing to read chapter after chapter of abstract theory and/or backgroundinformation beforehand. For example, if you want to learn how to build a portlet that displays agraphical chart, skip to Chapter 10, “Using Charts in Portlets;” if you want to find out how towork Ajax into your portlets, skip to Chapter 13, “Using Ajax and Dojo.” If you are completelynew to WPF (or portals and portlets) and are looking for some basic information to get youstarted in WPF, Chapter 1, “Introduction to WebSphere Portlet Factory,” provides an overview of

1 WebSphere Portlet Factory won the 2006 JavaPro readers’ choice award for “Best Java Enterprise Portal Technology”(www.fawcette.com/javapro/).

Page 31: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

portal terminology, WPF architecture, and the WPF Designer interface. Chapter 1 also walks youthrough the process of creating, testing, and deploying a simple Hello World! portlet. Other intro-ductory information is available in Appendix A, which contains some useful information for set-ting up your WPF development environment, and there is a glossary at the back of the book thatdefines common WPF terms.

This book also contains useful tidbits that I have picked up during my time with WPF—thesort of things developers need to know but normally wouldn’t without a great deal of experimen-tation and frustration. These snippets of information are highlighted as follows:

TIP

Tips contain useful information that can be employed in WPF, usually with the purpose ofexpediting portlet development. Tips are useful, but they are not critically important and canbe skipped if desired.

WARNING

Warnings are important points that usually obviate a common sticking point, and heedingthem may spare you future frustration.

Due to the width of the book’s printed page, some lines of code might be too long to fit ononly one line. If a line of code wraps to another line(s), and it’s not obvious it’s part of the preced-ing line, we have inserted a code continuation character ([ccc]) at the beginning of the runoverline to indicate that the code is part of the line preceding it. (You should type lines of code thathave this character as one long line without breaking it.) For example,

WebAppAccess remoteWebAppAccess =

�webAppAccess.getModelInstance(“modelPath/ModelName”, “”,

�false);

All the examples discussed in this book are available for download from ibmpressbooks.com/title/9780137134465. More advanced readers can import what they want from theseexamples directly into their projects, without necessarily consulting the book itself—althoughyou are encouraged to follow along with the examples to increase your understanding of WPF.By walking through each example, you will learn how to build portlets in WPF by actually build-ing them, and not just reading about it; so, by the end of each chapter, you should have a practicalunderstanding of how to work the discussed features into your own portlets.

Although this book does discuss the theory of WPF portlet development, this information isdiscussed in the context of the practical examples in the book, which gives you a more concrete

xxx Preface

Page 32: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

understanding of how the abstract side of portlet development is applied. Readers unconcernedwith what is going on under the covers can skip the theory sections without adversely affectingtheir portlets. Indeed, one of the advantages of using WPF is that you don’t need to learn vastamounts of theory to begin development—you can start building portlets right away. The focus ofthis book, then, is on the practical side of portlet development, with an emphasis on rapidly build-ing portlets with certain functionality—this is not intended as a book of theory. Similarly, givenits short length, this book is not intended to cover every aspect of portlet development—onlythose areas that are deemed most useful to portlet developers (and WPF developers, in particular).

I hope you find this book useful and enjoyable to read; I certainly enjoyed writing it. At theleast, I would like this book to go some way toward expediting your portlet development processand increasing your understanding of WPF. If you have any comments about the content or struc-ture of the book, feel free to drop me a line at [email protected]

Preface xxxi

Page 33: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 34: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

xxxiii

Acknowledgments

I’d like to extend my sincerest appreciation to everyone who supported me during the process ofwriting this book. In particular, I’d like to thank John Bergland and Dee Zepf for their early sup-port of the concept, and Jonathan Booth and Louise Simonds for their insightful comments andadvice. I’m eternally grateful to Katherine Bull, my acquisitions editor, for her continual supportand direction throughout the project; and to Kevin Howard, my development editor, who care-fully surveyed each chapter and made many helpful suggestions. Thanks also to Carlos Llopartfor the Spanish translations in Chapter 12, and to my sister Kirsten for providing several of thediagrams that appear in this book.

Of course, a thank you is also due to you, the reader, for purchasing this book and investingthe time to read it. I hope that this book increases your understanding of WebSphere Portlet Fac-tory and provides you with a valuable portlet development resource.

Page 35: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 36: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

xxxv

About the Author

David Bowley is a consultant for e-Centric Innovations, an e-business solution provider in Mel-bourne, Australia. Over the last nine years, David has worked extensively with IBM technologies,particularly WebSphere Portal and WebSphere Portlet Factory. David has a bachelor’s degree incomputing and holds numerous I.T. certifications in areas such as WebSphere Portal, WebSpherePortlet Factory, Java, Lotus Notes, .Net, DB2, Rational, SOA, and RUP. David is a frequent con-tributor to various technical publications, including The View and Lotus Advisor.

Page 37: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 38: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

1

C H A P T E R 1

Introduction toWebSphere PortletFactory

This chapter explains basic portal concepts (such as what portals and portlets are), and introducesthe fundamentals of portlet development using WebSphere Portlet Factory (WPF). By the end ofthe chapter, you will have a working Hello World! portlet and you will understand the basic con-cepts and techniques required to build, deploy, and test portlets using WPF. This chapter isintended for WPF newcomers, but those who are interested in brushing up on the basics of WPFshould also find something of interest in it. If you already feel confident using WPF, feel free toskip ahead to any of the later chapters—you can always come back to this chapter if you need to.

The files used in this chapter are available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 1 folder (instructions for copying these files into your projectare included in a readme.txt file in the same folder); however, to increase your understanding ofthe topics discussed, it is recommended that you create these files yourself by following theexample in this chapter. Doing so will give you a good understanding of the basics of WPF andposition you to tackle some of the other chapters in this book.

The following topics are covered in this chapter:

• What is a portal and what are portlets?

• Portal key benefits

• What is WebSphere Portlet Factory?

• WebSphere Portlet Factory key benefits

• WebSphere Portlet Factory architecture

• Introduction to the WebSphere Portlet Factory Designer

• Building your first portlet

Page 39: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

What Is a Portal and What Are Portlets?

A portal is a user interface (UI) for people to interact with information and processes, often viaWeb pages accessed using a Web browser (such as the portal shown in Figure 1.1). Portals areprovided by a portal server, such as WebSphere Portal Server, in a similar way to how Web pagesare provided by an ordinary Web server. Portals usually aim to streamline business operations bybringing together information and processes from disparate parts of an organization. Forexample, an online bookstore may provide a portal for customers to preview new releases, pur-chase new books, check the status of any current orders, and even chat with other customers toshare their thoughts on a particular book. Portal functionality is normally provided through oneor more portlets, which are UI components of the portal that serve a particular function (similarto how a window offers a particular function—or suite of functions—within a Microsoft® Win-dows® application). In the case of an online bookstore, then, a portal might include a NewReleases portlet and a Forum portlet.

2 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.1 An example portal at www.ibm.com/developerworks/.

Portlets are laid out onto various pages within the portal, each page effectively containing aset of portlets that serves a common purpose. So, a Purchase page might contain portlets for

Page 40: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

browsing a catalogue and for buying new books, and a Community page might contain portletsthat facilitate communication with other customers. Portals don’t necessarily have to be customerfacing; for example, an intranet portal might be available only to employees, and an extranet por-tal might be available only to suppliers. A portal can be anything from a simple front-end to abackend data source, to a complex collaborative tool integrating several different departmentsacross an enterprise.

Due to the current bandwidth limitations of the Web, portals are usually kept relativelysimple in comparison with more traditional rich clients (like Microsoft Word, for example). Sim-ilarly, portlets are not normally as packed with features as their rich client cousins, and they offera more focused service. As a result, portlets normally satisfy some key business requirement orprocess (either individually or in conjunction with other portlets). Having said this, portals avail-able through a Web browser can be accessed on a wide variety of platforms, using a number ofdifferent devices, and from anywhere in the world; so, potential exposure to a portal availablethrough a Web browser is vastly superior to that gained through a rich client. Careful considera-tion, then, needs to be applied to the portal design process, and a portal should aim to supplementrich client applications rather than replace them.

Portal Key Benefits

Depending on its exact nature, a portal usually offers one or more of the following key benefits:

• Integration of Business Functions—Probably the most common use for a portal is asan integrator of business functions, usually across departmental or technological bound-aries within an enterprise. For example, a portal might provide portlets for accessingaccounting applications in SAP, reports on a SQL server, and email capabilities fromLotus Domino®, and it can enable you to use these portlets (and even send informationbetween them) as if they were all part of the same system. This sort of integration pro-motes standardization of business processes and discourages the practice of viewing anorganization as a collection of isolated business units.

• Aggregation of Information—Another popular use for a portal is as an aggregator ofinformation—that is, as a means to bring together information from disparate locationsor data sources into a single interface (again, giving the impression that all of the infor-mation is stored in the same place). A portal can save users from needing to use severaldifferent programs to hunt through multiple systems in search of information.

• Collaboration between Users—Portals often provide functionality that facilitatescommunication and information sharing across an enterprise (such as document shar-ing, email, blogs, and project team rooms).

• Accessibility of Information and Services—One of the greatest features of the Web ishow it quickly and easily facilitates communication between people from vastly differ-ent locations and backgrounds. As a result, portals often provide an experience tailored

Portal Key Benefits 3

Page 41: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

to the context in which they are accessed. For example, a portal may be offered in sev-eral different languages, and different markups (such as HTML and WML) may be usedto allow access to the portal using different devices (such as mobile phones, laptops,PCs, and PDAs).

Portal servers also provide mechanisms to restrict accessibility through customizableauthentication and authorization mechanisms that can leverage an organization’s exist-ing security methods (such as Lightweight Directory Access Protocol [LDAP] andLotus Notes® Access Control Lists [ACL]). Putting this into practice, an employee froma sales department might be able to see only the sales portion of a portal, and an unau-thorized person might not be able to log on at all.

• User Interface Personalization—Portals often provide a certain degree of personaliza-tion, such as allowing customers to specify the information they see and how it shouldbe displayed. For example, a portal can provide facilities for end users to choose theposition of portlets on the page or to add and remove portlets as required.

What Is WPF?

WPF is a tool for Eclipse-based Integrated Development Environments (IDE) that facilitatesrapid application development. This is achieved primarily through the use of wizard-based,reusable components called builders, which can be parameterized based on different contexts andautomatically built into executable code.

Developers can create WPF applications by creating a WPF project in an Eclipse-basedIDE (such as Rational® Software Architect [RSA], Rational Application Developer [RAD], orEclipse itself), which has WPF installed into it. After it is installed, WPF adds new design arti-facts to the IDE that enable the development of WPF applications. WPF projects can then beautomatically assembled into Web ARrchive (WAR) files (a WAR file is an archive of Java designartifacts for a Web application) from the IDE and deployed to local or remote application serversor portal servers.

Note that although you can use any version of WPF to complete the examples in this book,it is assumed that you are using WPF 6.0.2.

WPF Key Benefits

Some of the key benefits of WPF are:

• Reduced Need for Hand Coding—Developers can build standards-based applications(such as portlets, Web services, or Java 2 Enterprise Edition [J2EE] applications) withlittle or no coding. Given the reduced need to write code, the skill set required to buildcomplex applications (in J2EE, for example) is drastically reduced.

• Faster Development Times—As WPF development is mostly wizard-based, it is lesserror prone than traditional development and can greatly speed up the development

4 Chapter 1 Introduction to WebSphere Portlet Factory

Page 42: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

process. WPF applications are also more flexible than traditional Java applications inthat they are easier to maintain and extend.

• Best Practices—WPF encourages component- and service-based design, and can beused to enforce architectural patterns and best practices.

• Powerful Capabilities—WPF has a suite of around 160 wizard-like builders that can beused to automate many common development tasks. These builders have strong integra-tion capabilities with a broad range of backend data sources.

WPFArchitecture

At design time, WPF applications consist of three main building blocks: builders, models, andprofiles. Developers work with these elements (along with other design elements like HTMLpages, XML documents, and Java classes) in a special type of project called a WebSphere PortletFactory project (see the “Introduction to the Eclipse IDE” sidebar later in this chapter if you areunfamiliar with projects in Eclipse). Using all of these elements, a WPF mechanism known as theFactory generation engine can automatically generate executable applications called WebApps.WPF can also automatically package these WebApps into different types of deployable WARfiles, which you can configure via deployment configurations.

Each of these elements is discussed in the following sections.

Builders

Builders are the basis of any WPF application; they are essentially wizard-based interfaces thatautomate common development tasks (see, for example, the SQL Call builder in Figure 1.2). Abuilder can do anything from add a button to a HTML page, to send data to a backend data source,to publish parts of an application as a Web service. Builders contain sets of parameters (oftencalled builder inputs or fields) that developers use to customize what they want a builder to do.You can modify builder inputs at any time and regenerate your application as many times as youlike. As of release 6.0.2, WPF contains about 160 builders, and developers are free to create theirown custom builders as well. Using builders encourages component-based design, and a custombuilder library can enforce architectural and coding standards across a development team.

For example, after a Domino Data Access builder call has been added to your project, youjust have to enter some parameters (such as a Domino database to connect to) and save yourchanges, after which WPF automatically generates all the appropriate code to access and manip-ulate the appropriate backend Domino database. You then use another builder call (or several,depending on the degree of customization required) to display and format data from the database.

Developers usually interact with builders through a graphical interface (shown in Figure1.2), but a combination of Java classes and XML files are used to create builders on the backend.Developers can manipulate these files to extend the pre-packaged builders or to create their ownbuilders. For an example of how to create your own builder, see Chapter 15, “Performance andProcess Optimization.”

WPFArchitecture 5

Page 43: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

6 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.2 The SQL Call builder.

Models

Developers assemble collections of builder calls inside models, which list what builders WPFshould use to generate your application and to store the specific values used for each builderinput. Through builder calls, models can link to other models as well; you might, for example,use one model for UI-related builder calls, which, in turn makes calls to another model for dataretrieval. Models are stored as XML files so they can be easily distributed, but are manipulated ina GUI using the WPF Designer. Structuring your projects with models enables you to build flex-ible, highly modular applications.

TIP

If a model contains an Action List builder called ‘main’, you can run the model directly fromyour IDE, which executes the sequence of actions defined in the main builder from the codegenerated by WPF. If a model contains a Portlet Adapter builder, when your application isgenerated, a portlet is created based on the builder calls in the model.

A single WPF project can contain one or more models, and subsequently can contain sev-eral portlets (when you deploy your project to a portal server, you will have access to all of theportlets contained in the project). For example, the Hello World! project built later in this chapter

Page 44: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

contains a single model consisting of several builders. One of these builders is a Portlet Adapterbuilder, which means that when you deploy the project to a portal server, a Hello World! portletwill become available.

Profiles

WPF uses profiles to facilitate context sensitive functionality in your applications and can actu-ally generate different applications for different contexts, roles, or settings. A profile is essentiallya set of values for one or more builder inputs, and WPF decides which of an application’s profilesto use based on certain conditions. These conditions can be anything from a user’s J2EE role, toan LDAP group, to a custom condition specified by the developer.

For example, you might set up two profiles for an application: one for administrators andone for ordinary users. The context in this case is the type of user (which might be specified in anLDAP group). Each profile might contain different values for certain builder inputs in your appli-cation (which might lead to different pages displaying or different execution paths being fol-lowed). Depending on how you configure your profiles, two separate applications might begenerated (one for each type of user); or perhaps only one application, which responds differentlydepending on the user who is accessing it.

Profiles are stored in files called profile sets, which have a .pset extension and can be foundunder the WebContent/WEB-INF/profiles directory in your project. For an example of how to useprofiles in your application, skip to Chapter 12, “Profiling Portlets.”

Generating and Executing the WebApp

Whenever you open, save, or apply changes to a model or builder call, a WPF mechanism knownas the Factory generation engine creates one or more executable versions of your model calledWebApps. WebApps consist of things like Java code, HTML pages, and XML files, and are builtaccording to the inputs in your builder calls. For example, a Page builder called page1 causes anHTML page called page1 to be created in a WebApp by the Factory generation engine. Whengenerating your WebApps, the actions taken by the Factory generation engine are determined bybackend Java classes for each builder used (called builder regeneration classes).

You can view the artifacts generated as part of the WebApp by selecting the WebApp Treetab, in the editor area of your IDE when you have a model currently selected (for more informa-tion on the WPF Designer interface, see “The User Interface” section later in this chapter). TheWebApp is also accessible via API calls made from Java or from inside other builders.

The design time generation process is shown diagrammatically in Figure 1.3. In step 1, youcreate your models, populate them with builder calls, and then assign values to the builder inputsthat these calls contain. In step 2, you generate a particular model (usually by saving one of itsbuilder calls), which causes the Factory generation engine to build a WebApp based on yourbuilder input values, using the corresponding builder regeneration classes.

WPFArchitecture 7

Page 45: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

8 Chapter 1 Introduction to WebSphere Portlet Factory

WebSphere PortletFactory Designer

Model A Model B

Model C Model D

Factory GenerationEngine

Builder 1 * Builder Inputs

Builder 2 * Builder Inputs

Builder 3 * Builder Inputs

WebApp

1

2

3

Pages Methods

Variables Comments

Properties Data Services

Events Schemes

Linked Java Objects

Model D

Builder Call 1 * Builder Inputs

Builder Call 2 * Builder Inputs

Builder Call 3 * Builder Inputs

Figure 1.3 The WebApp generation process at design time.

In step 3, you have the finished product: a WebApp, which contains all of the artifactsneeded by your application at runtime. If you have only one set of builder input values for a par-ticular model, you will have only one WebApp for that model. The Factory generation engine willcreate the WebApp using the appropriate builder regeneration classes, passing in values from thebuilder input values in the builder calls contained in that model.

However, if you profile your builder inputs, then after WPF regenerates your application, itis possible to have more than one WebApp for a single WPF model. For example, you might havetwo profiles in your application—one for administrators and one for ordinary users—each onespecifying different values for a particular builder. Subsequently, two WebApps will be created;one will use the values from the administrator’s profile, and the other will use the values from theordinary user’s profile. Figure 1.4 shows a diagram of this process.

Page 46: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

WPFArchitecture 9

WebApps

WebApp A WebApp A

WebSphere PortletFactory Designer

Model A Model B

Model C

Profile Sets

Model D

Factory GenerationEngine

1

2

3WebApp B

Pages Methods

Variables Comments

Properties Data Services

Events Schemes

Linked Java Objects

Model D

Builder Call 1 * Profiled Builder Inputs

Builder Call 2 * Builder Inputs

Builder Call 3 * Builder Inputs

Builder Call 1 * Profiled Builder Inputs

Builder 2 * Builder Inputs

Builder 3 * Builder Inputs

Figure 1.4 The WebApp generation process with profiling.

When WPF applications are executed on a server, they pass through several stages, andgeneration can occur during this process. The execution process is shown diagrammatically inFigure 1.5. In step 1, a user requests access to a WPF application, and the request is received bythe Factory controller servlet (WebEngineServlet) at step 2. The Factory controller servlet thenroutes the request to a WPF process called WebAppRunner in step 3. At step 4, the WebAppRun-ner process determines which profile (if any) to associate with the user request.

If no profile is required, then control skips to step 6. If a profile is required, then the profileis selected at step 5 and control proceeds to step 6. At step 6, a check is performed to see if anappropriate WebApp for the current request already exists in the cache (that is, one that matchesthe requested profile and model combination). If an appropriate WebApp does exist, then it isretrieved from the cache at step 7, and control passes to the final step, where an executableWebApp is made available. If an appropriate WebApp does not exist, then control passes tothe generation engine at step 8, and an appropriate WebApp is generated at step 9. Finally, anexecutable WebApp is available in step 10.

Page 47: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 1.5 The WebApp execution process.

Although the process of generating (and executing) your WebApps occurs mostly behindthe scenes in WPF, understanding it will enable you to make better sense of the WPF develop-ment process and ultimately enable you to directly manipulate the WebApp in your applications(via the WebApp API). Use of the WebApp API is discussed in Chapter 8, “Using Java inPortlets.”

10 Chapter 1 Introduction to WebSphere Portlet Factory

Factory controller servlet

Generation engine

WebApp generated

WebApp available

WebAppRunner

Is Profileneeded?

Is WebAppin cache?

WebApp retrieved

User request

1

2

3

4

5

6

7

8

9

10

Yes No

Yes No

Profile selected

Page 48: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Portlet Factory WAR Files

WPF applications can be automatically assembled into WAR files, which can then be deployed toan application server or portal server. Target servers for WAR deployment can be either local orremote to your development machine. There are three different types of WAR files you can createin WPF (one application can use all three WAR files simultaneously), and each one has slightlydifferent characteristics. The three different WAR files are discussed in each of the followingsections.

Development WAR

The development WAR contains functionality to assist development, which is not contained inthe other types of WAR files (such as the capability to run models directly from a URL). When-ever you run models directly from your IDE, you use the version of the WebApp contained in thedevelopment WAR.

The development WAR must be deployed to an application server. You can create develop-ment WARs by right-clicking your project and selecting Application Server WAR, Build WARfor dev testing; however, you need an application server deployment configuration before thisoption becomes available (deployment configurations are discussed in the “Deployment Configu-rations” section).

Portlet WAR

The portlet WAR contains functionality that enables you to run models as portlets within a portal,as well as take advantage of functionality offered by the portal (such as inter-communicationbetween portlets). This is not contained in the other WAR file types. Portlet WARs do not containany development-specific design elements, so they are suitable for any sort of environment (test,production, and so on).

The portlet WAR must be deployed to a portal server. You can create portlet WARs by right-clicking your project and selecting Portal Server WAR, Build Portlet WAR; however, you need aportal server deployment configuration before this option becomes available.

TIP

Even though you need a portlet WAR to view your models as portlets, you can still previewthese models as standalone Web applications using the development WAR. This is usefulfor quickly testing features of your portlets that don’t require functionality that is availableonly in the portal (such as inter-portlet communication). After testing, you can then create aportlet WAR to test any portal-specific functionality.

WPFArchitecture 11

Page 49: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Deployment WAR

The deployment WAR doesn’t contain any of the development artifacts included in the develop-ment WAR, and can’t take advantage of portal server specific functionality. You would normallyuse a deployment WAR when you want to deploy your application to a production environment,but don’t want to use any of the capabilities of a portal (for example, your application doesn’tcontain any portlets). You might create a Web service and deploy a deployment WAR to an appli-cation server in your production environment, so that the Web service is constantly available toexternal consumers. You can also use deployment WARs in test environments when you don’twant to include any unnecessary design artifacts in the application.

The deployment WAR must be deployed to an application server. You can create deploy-ment WARs by right-clicking your project and selecting Application Server WAR, Build WARfor a production deployment; however, you need an application server deployment configurationbefore this option becomes available.

Deployment Configurations

To run your applications, you need to deploy them to an application server or portal server. InWPF, you use deployment configurations to manage settings for these deployments. You can usetwo deployment configurations:

• Application server deployment configuration

• Deployment server deployment configuration

The application server deployment configuration is used mainly to specify settings for test-ing your application directly from the IDE. The development WAR and deployment WAR, if youare using them, are both deployed to the server specified in the application server deploymentconfiguration. The portal server deployment configuration specifies settings for deploying theportlet WAR to a portal server.

Running WPF portlets on a portal server lets you take advantage of the functionalityoffered by the portal (such as inter-portlet communication and user-configurable, shared-settingsmenus), and running your WPF portlets on an ordinary application server lets you view them asstandalone applications. There are advantages to both approaches (an application server is oftenquicker for testing, but doesn’t have all the functionality of a portal server), and common practiceis to use an application server for testing quick changes that don’t require functionality from theportal, and then use a portal server for testing portlets as they would appear in a production envi-ronment. WPF 6.0.2 comes with a lightweight application server called WAS CE, which is per-fect for local testing.

It is possible to link to local servers (those installed on the same machine as WPF) andremote servers (those installed on a different machine to WPF) from your deployment configura-tions, and each scenario has different advantages. Local servers are the easiest to set up as theydon’t require you to manually install WAR files; however, deploying to a remote server can free

12 Chapter 1 Introduction to WebSphere Portlet Factory

Page 50: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

up valuable resources on your development machine. If you want to have the capability to auto-matically refresh WAR files from your IDE (highly useful in test environments), you need to linkto servers that are installed either on your local machine or are accessible through the file systemvia a mapped drive. If you’re deploying to a remote machine that you can’t access through the filesystem, you have to manually update the installed application from the WAR file created by WPF.

TIP

When mapping to a remote server, you don’t need access to the entire file system. If secu-rity is a concern on the remote server, you should map only the application server or portalserver directories on the remote machine.Note that WAS 6 and WPS 6 both have multipleparent directories by default (usually c:\Program Files\IBM\WebSphere and c:\IBM).

Introduction to the WebSphere Portlet Factory Designer

The WebSphere Portlet Factory Designer (or WPF Designer) is an Eclipse-based IDE with theWPF software installed (as a result, the terms IDE and WPF Designer are often used interchange-ably throughout this book). WPF Designer enables developers to create WPF applications and toutilize WPF-specific design elements such as builders, models, and profiles in their projects.

The User Interface

After WPF Designer is installed (see Appendix A, “Setting Up Your Environment,” if you wantmore information on how to do this), developers should switch to the WebSphere Portlet Factoryperspective if it is not already visible (if you are unfamiliar with the term perspective, please seethe “Introduction to the Eclipse IDE” sidebar). You can switch to the WebSphere Portlet Factoryperspective by selecting Window, Open Perspective, Other, selecting WebSphere Portlet Factoryfrom the list, and then pressing OK. After the WebSphere Portlet Factory perspective loads, yourIDE should display similar to the screenshot shown in Figure 1.6 (note that there may be slightdifferences depending on the version of WPF you use).

TIP

You don’t necessarily have to use the WebSphere Portlet Factory perspective if you don’twant to, but it does provide you with an easy-to-use interface with several commonly usedviews.You can switch between perspectives at any time by selecting Window, Open Per-spective, Other, and then selecting the appropriate perspective from the list; you can evencreate your own perspective by adding and removing views and editors (which you can dofrom the Window menu in the IDE).You can then save your perspective by selecting Win-dow, Save Perspective As, giving your perspective a name, and pressing OK.

Introduction to the WebSphere Portlet Factory Designer 13

Page 51: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 1.6 The WebSphere Portlet Factory perspective.

As with any other Web applications, your development artifacts display in the ProjectExplorer view on the left side of the screen (or in the Navigator if you’re using a version of WPFprior to 6.0.1), which is in section 1 of Figure 1.6. If you are using WPF 6.0.2 or later, underneaththe models in this section, you will also see a list of artifacts referenced by the model (such asHTML files and images). The builder calls in the currently active model are displayed below thisview in the Outline view, contained in section 2. You can edit a builder call by double-clicking it,and you can add new builder calls to the model by clicking the icon in the top right of the Out-line view.

The top-right quadrant of the IDE (contained in section 3 of Figure 1.6) displays editors fora number of different aspects of your application, depending on what you currently have open inthe IDE. If you have a model currently selected (you can select a model by double-clicking on itin the Project Explorer view), then this section of the screen displays the Model Editor, whichcontains a series of tabs for the model. These tabs are WebApp Tree, Model XML, Builder CallEditor, and WebApp Diagram.

14 Chapter 1 Introduction to WebSphere Portlet Factory

Project Explorer view Model Editor

Problems viewOutline view

Page 52: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The WebApp Tree tab (shown open in Figure 1.6) gives you a hierarchical display of theitems used in your WebApps and a read-only view of the code generated by the generationengine. The Model XML tab (shown in Figure 1.7) gives you a read-only view of the backendXML representation of your model.

Introduction to the WebSphere Portlet Factory Designer 15

Figure 1.7 The Model XML tab.

The WebApp Diagram tab (shown in Figure 1.8) gives you a diagrammatic representationof the execution flow in your WebApps. Switching between these tabs gives you a different viewof the currently active model.

The Model Editor tab (shown in Figure 1.9) enables you to edit the currently active buildercall in your model. To open a builder call in the Model Editor, simply double-click on the appro-priate builder call in Outline view.

TIP

Perusing the WebApp Tree tab is a great way to see what the generation engine is doing onthe backend and can really improve your understanding of WPF. Also, code snippets fromthe WebApp Tree tab can be copied and pasted into your own code. Using the WebAppcode can help you learn the WPF Application Programming Interface (API), and it will alsohelp Java novices improve their Java skills.

Page 53: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

16 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.8 The WebApp Diagram tab.

Figure 1.9 The Builder Call Editor tab.

Page 54: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

If you are not currently editing a model or builder, the top-right quadrant of the screen canalso be used to display editors opened from other views in the IDE. For example, double-clickingan XML file in the Project Explorer view opens that XML file in a text editor, and double-clickingon a Java source file opens the code in a code editor.

The final portion of the screen shows the Problems view (contained in section 4 of Figure1.6), which displays any errors with your project or with the generation of your application.Another useful view in this section of the screen is the Applied Profiles view, which lets you sim-ulate what your application would do when a particular profile is used. For example, you can testwhat your application would do when an administrator accesses your portlet, without actuallyhaving to log in to the portal as an administrator. You can switch to this view by clicking theApplied Profiles tab next to the Problems tab in the WPF Designer.

INTRODUCTION TO THE ECLIPSE IDE

There are several fundamental concepts that newcomers to Eclipse-based IDEs (such asRAD, RSA, or Eclipse) should be familiar with before using WPF:

Project—A project is a container for all of the design artifacts in your application. Thereare different types of projects for different types of applications; for example, a Web project isused to create standard Web applications, and a WebSphere Portlet Factory project is usedto create WPF applications.You can create projects by selecting File, New, Project in the IDE.

View—A view is a window in the IDE used to display, organize, or navigate through infor-mation.The Problems view, which displays errors in your application and with the generationprocess, is an example of a view. You can add new views to the IDE by selecting Window,Show view, Other.

Editor—An editor (such as the Model Editor) is a window in the IDE used to enter andsave information for your project.You can open an editor for a file by double-clicking that filefrom a view in your IDE.You can assign particular editors to file types by selecting Window,Preferences, and then navigating to the General, Editors, File associations category.

Perspective—A perspective is a particular arrangement of views and editors in the IDE.The WebSphere Portlet Factory perspective, for example, contains the views and editorsthat are most conducive to WPF development. You can switch between perspectives byselecting Window, Open Perspective, Other in the IDE.

Workspace—A workspace contains IDE settings and a set of projects that you’re work-ing on. For example, you might have a workspace that contains all of your WPF projects andanother workspace for all of your standard Java projects. You can switch between work-spaces by selecting File, Switch Workspace in the IDE.

Folder Structure

WPF projects are organized into several different folders by default, which you can navigatethrough using the Project Explorer view (the main folders are shown in Figure 1.10). Double-clicking on a file in the Project Explorer view opens it in an editor, provided there is an editor for

Introduction to the WebSphere Portlet Factory Designer 17

Page 55: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

that file type available. The default links and folders displayed in the Project Explorer are dis-cussed in the following sections (please note that earlier versions of WPF may have a slightly dif-ferent file structure).

18 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.10 Default WPF folders shown in the Project Explorer view.

Models

This folder holds all of the models in your project. Note that this folder is actually the same as theWebContent/WEB-INF/models directory, so files stored in either of these directories display inboth locations.

Profiles

This folder contains all of the profile sets in your project (profile sets have a .pset extension andcan be opened in a Profile Set Editor by double-clicking the appropriate profile set in the ProjectExplorer view). As with models, this folder is actually the same as a folder under the WebContentdirectory (WebContent/WEB-INF/profiles), so if you modify any of your profile sets, both direc-tories will reflect the changes.

Page 56: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

WebContent/WEB-INF/work/source

This folder contains all of the Java source code for your project. The WPF designer automaticallycompiles any .java file that is saved in this directory and reports any errors in the Problems view(the corresponding .class files are stored in the WebContent/WEB-INF/work/classes directory).

JRE System Library

The JRE system library contains all of the libraries required for the Java Runtime Environment(JRE), and is not directly accessible from the Project Explorer view. You should switch to thePackage Explorer view if you want to view the contents of the JRE system library.

WebContent

The WebContent folder stores all the design artifacts in your project that are directly servable toclients (that is, they can be accessed directly in a Web browser), with the exception of the contentsof the WEB-INF directory. An index.jsp file in the WebContent directory enables you to browsethrough all the models in your project and run them from a Web browser (note that this artifactexists only in the development WAR, so you don’t have to worry about end users browsingthrough your models in a production environment). Additionally, the WebContent directory usu-ally contains your web.xml and portlet.xml files, which are descriptors used to define your appli-cation to the target server. You don’t have to edit these files directly, as WPF will edit them foryou when your application is regenerated.

TIP

You can make changes to the web.xml file yourself, but be aware that parts of the file areautomatically updated by WPF. The parts that WPF automatically updates are clearlymarked, so you shouldn’t run into any problems. The portlet.xml file, however, is completelyrewritten every time your application is rebuilt, based on settings in your Portlet Adapterbuilder—so any direct changes you make to the portlet.xml file are lost.

Several options are available if you want to make changes to the portlet.xml file that arenot covered by the Portlet Adapter builder. First, you can manually edit the portlet.xml fileafter it has been created, although this is not recommended as you need to do it every timethe application is rebuilt. Second, you can modify the configuration files in the WebCon-tent/WEB-INF/bin/deployment directory of your project. Both approaches can be supple-mented with a third option, which involves using a custom builder to update the portlet.xmlfile. Creating a custom builder is covered in Chapter 15.

The WebContent directory contains three main directories:

• A factory directory, which contains core WPF resources, such as HTML pages

• A META-INF directory, which stores meta information about your project

• A WEB-INF directory, which contains all of the design elements that aren’t directlyservable to clients (such as Java classes, models, and profiles)

Introduction to the WebSphere Portlet Factory Designer 19

Page 57: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The WEB-INF directory usually contains most of the files in your project and is split upinto a number of subdirectories (shown in Table 1.1).

Table 1.1 WEB-INF Subdirectories

Directory Name Description

bin The bin directory contains various batch files you can use to assist in thedevelopment process, such as obscure.bat (which encrypts passwords foryou).

builders Contains builder definitions used in WPF.

classes Contains deployable class files. You don’t need to directly change anythingin this folder.

clientLibs Contains deployable JAR files.

config This directory contains configuration files for your project. Configurationfiles can be used to configure everything from logging settings to server set-tings. They are discussed further in Appendix B, “Portlet Factory Properties.”

factory Contains core WPF design artifacts that are not directly servable to clients,such as XML data definitions and SQL scripts.

lib Contains all of the JAR files used by WPF.

logs In addition to more traditional Java logging methods, WPF has its own log-ging mechanisms that incorporate log4j logging. The results of these loggingprocesses are stored in the logs directory. For more information on usinglogs in WPF, see Chapter 14, “Error Handling, Logging, and Debugging.”

manifests Contains a manifest of all the files in your project.

models This directory is the same directory as the models directory that displays atthe top level of your project hierarchy in the Project Explorer view; it storesall of the models in your project.

profiles This directory is the same directory as the profiles directory that displays atthe top level of your project hierarchy in the Project Explorer view; it storesall of the profile sets in your project.

script_templates Contains any .jst templates in your application.

work The work/source folder contains all of your Java source code (the samefolder as the one that displays at the top level of your project hierarchy), andthe work/classes folder contains all the compiled versions of these files.

20 Chapter 1 Introduction to WebSphere Portlet Factory

Page 58: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

By default, the source folder is not displayed under the work directory, so if you want to editsource code, use the WebContent/WEB-INF/work/source folder at the top level of yourproject hierarchy. Note also that you shouldn’t edit the class files directly, as they are auto-matically overwritten by the WPF Designer every time you save a Java source file.

Building Your First Portlet

This section walks you through the process of creating a simple Hello World! portlet, deploying itto an application server and portal server, and then testing it. If you can successfully complete theportlet discussed in this example, then you will understand enough about the fundamentals ofWPF that you shouldn’t have any problems with building, testing, or deploying in future chapters.

Before you proceed, you need to decide which server(s) you are going to deploy to. Youwill then link to these server(s) when you set up your deployment configurations. If you haveboth local and remote servers available, you need to make a choice about which ones are the bestto use. Local servers are certainly more convenient for testing purposes, but may not be practicalif you’re using a slow machine or have limited server licenses. Instructions for both remote andlocal deployment are discussed over the course of the example.

The example in this chapter uses both types of deployment configuration (applicationserver and portal server). For the application server deployment configuration, you will see howto point to a local WAS CE server or WebSphere Application Server, and for the portal serverdeployment configuration, you will see how to point to a local WebSphere Portal 6 server(although the deployment process is fairly similar across different server versions). Note thatbecause a portal server is actually a normal application server with a portal framework, you canactually use a portal server for both deployment configurations; however, you can’t use an ordi-nary application server for your portal server deployment configuration (as it doesn’t have a por-tal framework).

If you need more information on setting up your development environment (installing WPF,configuring your portal server, and so on), please refer to Appendix A for more information.

Creating a Project

This section walks through the process of creating a new Hello World! project in WPF, and dis-cusses how to set up your deployment configurations. This project contains a simple model thatwill be surfaced to a portal server as a portlet.

To create a project, first select File, New, WebSphere Portlet Factory Project in the WPFDesigner to start the Create Portlet Factory Project wizard. If this option is unavailable, selectFile, New, Other, select WebSphere Portlet Factory Project from the WebSphere Portlet Factorycategory, and then press Next.

Building Your First Portlet 21

Page 59: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Type in a name for the project (such as WPFSandpit), and press Next when you are fin-ished. Note that the project you create in this section can be reused in the other chapters of thisbook, so you should name the project accordingly. The next screen (shown in Figure 1.11)enables you to specify feature sets to add to your project. Feature sets give you access to addi-tional sets of builders and can be added to a project at any time. You use some of these feature setselsewhere in this book, but for now, don’t select any feature sets and press Next.

22 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.11 Specifying feature sets for your project.

The next screen displays the Java build settings for your project (for more information onusing Java in your portlets, see Chapter 8. For now, press Next to accept the default settings. Thenext screen enables you to specify your deployment configurations.

Setting Up an Application Server Deployment Configuration

If you installed WPF with WAS CE, then you already have an application server deployment con-figuration called myWASCE1. Select this configuration if you have it, and skip to the “Setting Upa Portal Server Deployment Configuration” section later in this chapter. If you don’t have anapplication server deployment configuration, you need to create one.

Page 60: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

To create an application server deployment configuration, press the Add button in the appli-cation server deployment section of the screen. The New Deployment Configuration window dis-plays. Give your new configuration an appropriate name without using any spaces (such asApplicationServer6). Type a description for your configuration (such as Deployment con-figuration for WAS 6), and then select a server from the Server Type dropdown (such asWebSphere Application Server 6.x if you are using WebSphere Portal 6.0 as your target server).After you select a server, some extra options should display below the server type dropdown.

Every application server has a directory for its installed applications called installedApps.Type in the location of the installed applications directory for your application server in theInstalled Applications Dir box. Then, type in the hostname for your application server in theServer Host box (you can use localhost if the server is on the same machine as WPF) and the porton which you access applications on the server in the Server Port box.

If your application server is readily available and running, enable the checkbox for SpecifyDeployment Credentials, enter the WAS server name, and enter the username and password of auser who has access to deploy applications on the server. This gives you the option of deployingyour application directly from the IDE; if you do not select it, you need to deploy it manually onthe application server (this is covered in the “Manual Deployment” section).

WARNING

If you use WebSphere Portal Server in your application server deployment configuration,you should specify the name of the portal server for the WAS Server for deployment drop-down (WebSphere_Portal by default) rather than the name of the application server(server1 by default).

Press OK to save your application server deployment configuration. Note that if you haveenabled the Specify Deployment Credentials checkbox, your connection to the server may beautomatically tested when you press the OK button. You can also test your connection by press-ing the Test Server Connection button, although WPF will still test your settings when you try tosave the configuration. Depending on your server’s security settings, WPF might prompt you fora username and password (you can use the same username and password you just specified).After you have connected, you should see a success message, as shown in Figure 1.12.

WARNING

Testing your application server connection may yield a success message even when theserver port is wrong. If you are unsure about the server port, make sure you can access appli-cations on the server from the port you’ve specified. Some of the default server ports are:

WebSphere Portal 6: 10038WebSphere Portal 5.1: 9081WebSphere Application Server 6: 10000WebSphere Application Server 5.1: 9080

Building Your First Portlet 23

Page 61: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 1.12 Message to indicate a successful test of the server connection.

Setting Up a Portal Server Deployment Configuration

The next step is to set up a portal server deployment configuration. To do this, first press the por-tal server Add button from the Deployment Configuration screen in the Create Portlet FactoryProject wizard.

The New Deployment Configuration window displays. Give your new configuration anappropriate name, such as PortalServer6 (don’t use any spaces). Then, type a description foryour configuration (such as Deployment configuration for WPS 6), and select a serverfrom the Server Type dropdown (such as WebSphere Portal 6.x). Some extra options should dis-play under the server type dropdown.

Leave Java Standard selected as your Portlet API—this means that any portlets you buildwill be based on the JSR-168 specification, which is an industry standard set of APIs for buildingJava portlets.

WARNING

If you are using a version of WebSphere Portal server prior to version 5.1, you might needto set the Portlet API to WebSphere Native (deprecated), as WebSphere Portal serversprior to version 5.1 do not support the Java Standard API by default. To deploy to Web-Sphere Portal 5.0 or earlier, you also need to use WPF 5.x instead of WPF 6.x.

If your portal server is accessible through the file system, you can deploy to it directly fromthe IDE. To set this up, type the root directory for the portal server in the WP Root box (forexample, C:\Program Files\IBM\WebSphere6\PortalServer). Enable the checkbox for SpecifyDeployment Credentials, and then specify a username and password for a user who has access todeploy portlets to the server. The Admin URL field should automatically point to the config sec-tion of your portal server (this is the portal hostname, followed by the port number, followed by/wps/config), and the JRE Home field should automatically point to the bin directory where yourJava Runtime Environment (JRE) is installed (change these fields if they point to the wrong loca-tions). Press OK when you are finished, and your username and password will automatically betested against the portal server specified.

24 Chapter 1 Introduction to WebSphere Portlet Factory

Page 62: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

If you want to deploy to a server that is not accessible through the file system, disable theSpecify Deployment Credentials checkbox. The label for the field WP Root will change to ‘Warlocation’, and you should specify where you would like to store the deployable WAR file in thisfield. After the WAR file has been created, you need to manually deploy it to the remote server(this is covered in the next section, “Manual Deployment”).

Press OK to save your portal server deployment configuration. If you clicked the SpecifyDeployment Credentials checkbox, WPF automatically tests your settings to see if the connectionis valid—upon completion, you should see the same success message shown earlier in Figure 1.12.

TIP

A number of errors can occur when you try to save a deployment configuration. The mostcommon errors are caused by incorrect passwords or insufficient access to deploy portletsto the target server. Note also that an invalid port number can cause the portal serverdeployment configuration test to fail, although this is not the case for the application serverdeployment configuration.

The Deployment Configuration dialog should now contain details for each of your deploy-ment configurations. Press Finish when you are satisfied with your settings. A dialog box thenprompts you to confirm whether you would like to deploy your project. Select Yes, which createsdeployable WAR files for your deployment configurations and (if you clicked either of the Spec-ify Deployment Credentials checkboxes) also deploys them automatically. This process may takeanywhere up to several minutes depending on the speed of your machine and the speed of theservers involved. Depending on your server’s security settings, WPF may also prompt you for ausername and password for your application server (you can use the same username and pass-word specified when you set up the application server deployment configuration).

Note that the WAR file for the application server deployment configuration is stored insidean EAR file. Either file can be deployed when not deploying to a portal server, but it’s easier todeploy using the EAR file because you don’t have to specify a context for your application duringthe installation process. When WPF has finished setting up your project, creating your WAR files,and deploying them to any target servers, control is returned to the IDE.

TIP

You should check the Problems view in your IDE after you’ve set up your deployment config-urations to ensure your application has deployed correctly. One of the most common errorsat this stage is specifying a username and password for the portal server administrator (ifprompted for it in the deployment process), whereas what is required is the username andpassword for the application server administrator (although these settings could refer to thesame user in many cases). Note that if you are connecting to a remote server from WPF,you will receive an error indicating that the application needs to be deployed. Instructions formanually deploying an application are discussed in the “Manual Deployment” section.

Building Your First Portlet 25

Page 63: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

You have now successfully created a WPF project and set up both your application serverdeployment configuration and portal server configurations. If you enabled the Specify Deploy-ment Credentials checkboxes, then you also have deployed WAR files to each server (a develop-ment WAR to the application server and a portlet WAR to the portal server). In the future, if youwant to set or modify your deployment configurations for an existing WPF project, you can dothis from the WebSphere Portlet Factory/Deployment Info section of the Project Properties dia-log, which you can open by selecting the root folder of your project, and then selecting Propertiesfrom the Project menu in the menu bar at the top of the IDE.

If you set up automatic deployment, you can skip to the “Testing the Application” section.Otherwise, you need to manually deploy your application, which is discussed in the next section,“Manual Deployment.”

Manual Deployment

If you did not enable the Specify Deployment Credentials checkbox in either of your deploymentconfigurations, you need to manually deploy your application to that server(s). Manual deploy-ment of the development WAR (created via the application server deployment configuration) andthe portlet WAR (created via the portal server deployment configuration) are discussed in the fol-lowing sections.

Application Server Deployment Configuration

To manually deploy an application to an application server, first open the applicationserver administration console in a Web browser (for example, http://myApplicationServer.com:10001/ibm/console). The administration console can also be opened from the Start menu.

Expand the Applications section and click Install New Application, as shown in Figure1.13. In the Local file system box, enter the path to the EAR file you created earlier, which con-tains the development WAR file (or use the Remote file system box if you can’t access the filelocally). By default, this EAR file will have been created in the installableApps directory on theapplication server when you set up your deployment configurations (in the example, the directoryX:\ibm\WebSphere\profiles\wp_profile\installableApps is used). Press Next, and then press Yesif prompted to display non-secure items.

You can accept the defaults on the next few screens by pressing Next at each screen (untilyou are asked to press the Finish button). The first screen contains settings for bindings and map-pings, the second screen contains basic deployment options, and the third screen enables you tomap modules in your application to particular servers. The fourth screen contains settings for vir-tual host mappings, followed by a screen containing settings for mapping security roles to usersand groups.

The final screen contains a summary of your previous settings. Review these settings, andthen click Finish to install the application. You will see a success screen similar to the one dis-played in Figure 1.14. Click the ‘Save to master configuration’ link to save the new settings. Onthe confirmation screen that displays, press Save.

26 Chapter 1 Introduction to WebSphere Portlet Factory

Page 64: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Building Your First Portlet 27

Figure 1.13 Installing a new application through the administration console.

Figure 1.14 Message received after successfully installing an application.

You have now installed the application, but you need to start the application before it can berun. To do this, click Enterprise Applications from the sidebar and scroll through the list of appli-cations to find the HelloWorld application (it will have a red cross next to it, which indicates thatthe application is currently stopped). Enable the checkbox next to the HelloWorld application andpress the Start button (as highlighted in Figure 1.15) to start the application. A success messagewill display, and you should be able to run the application.

Note that it is required you go through this process only once for each development WARfile. You can set up your project so that it automatically updates the deployed WAR by openingthe Project Properties dialog box, selecting WebSphere Portlet Factory Project Properties, andthen typing in the directory where your application is deployed into the Development WAR loca-tion field (also, you need to enable the checkbox for automatically synchronizing the dev WAR).This causes changes in your project to automatically update the deployed application wheneveryou save resources in the IDE. After you have this configured, you can also force a synchroniza-tion of the files in your project with the deployed WAR by right-clicking the root folder of yourproject in the IDE, clicking on Application Server WAR, and then selecting ‘Synchronize (copy)modified files’. Synchronizing the development WAR removes any errors in the Problems viewassociated with the development WAR not yet being deployed.

Page 65: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Note, however, that certain changes (such as removing files from an application) mayrequire a rebuild as opposed to synchronization. You can rebuild your development WAR byright-clicking the root folder of your project in the IDE and selecting Application Server WAR,Build WAR for dev testing.

28 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.15 Starting the HelloWorld application.

Portal Server Deployment Configuration

Although it is possible to use the administration console to deploy the portlet WAR, this sectiondescribes how to use the portal’s administration interface, which is quicker and slightly easierthan using the administration console (but you can’t use it to deploy to an ordinary applicationserver).

To manually deploy an application for a portal server deployment configuration, log in tothe portal as an administrator, and then open the Administration page. Click Web Modules underthe Portlet Management heading (see Figure 1.16) to open the Manage Web Modules portlet.

Click the Install button on the Manage Web Modules portlet, and then enter the path to yourportlet WAR file in the Web Modules portlet. By default, this WAR file has have been created in thedirectory specified in the WAR location field in the portlet deployment configuration (X:\ProgramFiles\IBM\WebSphere6\PortalServer\installableApps\HelloWorld.war was used in the example).Press Next.

A list of the portlets that this application contains is listed on the next screen. Press Finishto install your application.

You should see a success message at the top of the Manage Web Modules portlet, as shownin Figure 1.17. Your portlet WAR file is deployed, started, and ready to use (there is no need tomanually start the application).

Page 66: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Building Your First Portlet 29

Figure 1.17 Success message after installing the HelloWorld application.

Note that it is required you go through this process only once for each portlet WAR file. Youcan set up your project so that it automatically updates the deployed WAR by opening the ProjectProperties dialog, selecting WebSphere Portlet Factory Project Properties, and then typing in thedirectory where your application is deployed into the Portlet WAR location field (also, you needto enable the checkbox for automatically synchronizing the portlet WAR). This causes changes inyour project to automatically update the deployed application whenever you save resources in theIDE. After you have this configured, you can also force a synchronization of the files in yourproject with the deployed WAR by right-clicking the root folder of your project in the IDE, click-ing on Portal Server WAR, and then selecting Synchronize (copy) modified files. Synchronizingthe portlet WAR removes any errors in the Problems view associated with the portlet WAR notyet being deployed.

Note, however, that certain changes (removing files or actions that affect the portlet.xmlfile, such as adding portlets to an application) require a rebuild as opposed to synchronization.You can rebuild your portlet WAR by right-clicking the root folder of your project in the IDE andselecting Portal Server WAR, Build Portlet WAR.

After you have deployed your application manually to the appropriate server(s), you shouldproceed to the next section, which discusses how to test your application.

Figure 1.16 Opening the Web Modules page.

Page 67: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Model

You should now add a model to your WPF project, which will be used to test your application anddeployment configurations. A Portlet Adapter builder will be added to the model. This means thatwhen the model is deployed to a portal server, it will be available as a portlet (a screenshot of theportlet is shown later in Figure 1.22). When run on an ordinary application server, the model runsas a standalone Web application rather than as a portlet (as shown in Figure 1.20). The differencesbetween these two scenarios become clearer when you test the application in the next section.

To add a model to your project, select File, New, WebSphere Portlet Factory Model in theWPF Designer to start the Create Portlet Factory Project wizard. If this option is unavailable,select File, New, Other, and then select WebSphere Portlet Factory Model from the WebSpherePortlet Factory category. Press Next. On the next screen, select the WPF project you created ear-lier and press Next.

The next screen lists different types of models WPF can automatically create for you. Notethat the list of model types you see on this screen will differ depending on the feature sets youhave enabled in the project. The model types on this screen have a particular default configurationof builders best suited to a particular purpose, although you can always add these builders manu-ally as well. Chapter 3, “Using Data from a Relational Data Source,” and Chapter 4, “UsingDomino Data,” discuss how you can use some of the model types on this screen to automaticallycreate models tailored to accessing and displaying data.

Select the Main and Page option to create a basic model that simply displays a page to thescreen, and then press Next. Then select Simple Page from the Page Settings screen and pressNext again. The Simple Page option causes WPF to create a default page for you, so you don’thave to supply your own. Give your model the name testDeployment, and make sure it is cre-ated in the directory models/chapter01. Press Finish to build your model. This creates a newmodel called testDeployment in your WPF project and opens the model in the Model Editor andOutline view.

To surface this model as a portlet on a portal server, you need to add a Portlet Adapterbuilder to the model. To do this, open the Builder Palette by pressing the icon in the Outlineview in your IDE. Select Portlet Adapter from the list as shown in Figure 1.18, and then pressOK. This adds a Portlet Adapter builder to your model and opens it in the Model Editor.

You need to give the Portlet Adapter a name, portlet title, and portlet description. The nameis the name of the Portlet Adapter builder as it displays in Outline view, and the portlet title is thename of the portlet as it displays in the portal. The portlet description displays on several con-figuration screens in the portal and can be used as a search key to find the portlet. EnterhelloWorld for the name and Hello World! for the portlet title. For the portlet description,type This portlet tests my deployment configurations. (Note that you can’t useany spaces in the name, but you can use spaces in the portlet title and portlet description.)

30 Chapter 1 Introduction to WebSphere Portlet Factory

Page 68: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 1.18 Selecting the Portlet Adapter builder.

TIP

Note that the portlet title is blank by default, so any time you add a Portlet Adapter builder toa model, make sure you enter a value for the Portlet Title field. If you leave the Portlet Titlefield blank, the name of the model is used for the portlet title (which is usually undesirable).

Save the Portlet Adapter builder call by pressing Ctrl+S. Select Yes when prompted to savethe modified builder calls.

Your project now contains a model called testDeployment, and it is ready to be tested.

Testing the Application

In this section, you test your Hello World application—first as a standalone Web application rundirectly from the IDE (which tests the deployed application linked to the application serverdeployment configuration), and then as a portlet running on a portal server (which tests thedeployed application linked to the portal server deployment configuration).

First, you need to set up a run configuration, which contains basic settings for how youwant to run your applications from the IDE. To begin setting up a run configuration, select theRun option from the Run menu in your IDE. This opens the Run dialog, as shown in Figure 1.19.

Building Your First Portlet 31

Page 69: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

32 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.19 The Run dialog.

Double-click on the WebSphere Portlet Factory Model category. This creates a new config-uration called New_configuration, which displays under the WebSphere Portlet Factory Modelheading.

TIP

You don’t need to use the Run menu every time you want to run your application.You canexecute the last run configuration you used by pressing the button in your IDE.

Change the name of the configuration to something more meaningful (WPF run config-uration, for example), and press the Run button to preview your application. This runs the cur-rently active model (testDeployment, in this case) in your default Web browser. If your browserdisplays the output shown in Figure 1.20, the deployed application described by your applicationserver deployment configuration is working correctly.

Page 70: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 1.20 Testing your application on an application server.

TIP

If you don’t see the output in your Web browser, make sure the application server is runningand your application server deployment configuration settings are correct. Also, if you didn’tenable the Specify Deployment Credentials checkbox in your application server deploy-ment configuration, make sure that your application installed without any errors and hasbeen started (see the previous section, “Manual Deployment,” for an explanation of how todo this).

The next step is to test the deployed application described by the portal server deploymentconfiguration. To do this, you need to rebuild the deployed application on the portal server. If youenabled the Specify Deployment Credentials checkbox in the portal server deployment configu-ration, changes to your project will, in most cases, automatically update the deployed application,and there will be no need to rebuild. However, there are exceptions to this: If you remove filesfrom your project or modify the portlet.xml file (which you do indirectly when you add portletsor rename portlets), you need to rebuild.

The best way to rebuild your application (provided you use the Specify Deployment Cre-dentials option for your portal server configuration) is to right-click the HelloWorld project rootfolder in your IDE, and then select Portal Server WAR, Build Portlet WAR. This rebuilds both thedeployable portlet WAR file and the installed portlet application. If you’re not using the Specify

Building Your First Portlet 33

Page 71: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Deployment Credentials option, you need to manually redeploy (which is covered in the “ManualDeployment” section of this chapter). Note that you can rebuild your deployed portlet applicationat any time by right-clicking on the project root folder and selecting Portal Server WAR, BuildPortlet WAR (provided you are using the Specify Deployment Credentials option for your portalserver configuration).

WARNING

Some versions of WebSphere Portal Server 6.0.x do not recognize rebuilt applications.If you use WebSphere Portal 6.0.x and you find that the deployed application does notupdate after a rebuild, you may need to restart the application.You can restart an applica-tion from the administration console or by restarting the server.

After your deployed portlet application has been rebuilt, you need to add the Hello World!portlet to a page in the portal so you can see it. To do this, log in to the portal as an administrator,and then open the Portlet Palette by navigating to the target page in the portal and pressing the icon in the top-right corner of the portal (note that the location of this icon may differ if you use acustom theme or a version of WebSphere Portal other than version 6.0).

After the Portlet Palette opens, type Hello World! in the Search box and press the mag-nifying glass icon. The Hello World! portlet should display as shown in Figure 1.21.

34 Chapter 1 Introduction to WebSphere Portlet Factory

Figure 1.21 Finding the Hello World! portlet.

Click and drag the Hello World! portlet onto the page where you would like it displayed.The portlet should display as shown in Figure 1.22. Press the icon again to close the PortletPalette.

Page 72: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 1.22 The Hello World! portlet.

Summary

In this chapter, you learned about the basic building blocks of a WPF application: builders, mod-els, and profiles, and how the Factory generation engine works behind the scenes to assembleexecutable applications (called WebApps) based on the builder calls in your models. You alsolearned about the different types of WAR files you can produce from WPF (development WAR,portlet WAR, and deployment WAR) and the corresponding deployment configurations needed todeploy these WAR files to target application servers or portal servers. Finally, you learned abouthow to use the WebSphere Portlet Factory perspective in the WPF Designer, and created,deployed, and tested a simple Hello World! portlet.

Now that you understand the fundamentals of WPF, you should be able to start building anyof the other examples discussed in this book. Learning WPF largely consists of familiarizingyourself with the various builders, so spend some time experimenting with the builder calls avail-able and working through the examples in this book that interest you. WPF is an invaluable devel-opment tool with a broad range of potential applications, and the more you use it, the more easilyand quickly you will build your own portlets.

The next chapter, “Providing and Consuming Services,” describes how to incorporate ser-vices into your portlets using the service provider/consumer pattern.

Important Points

• Portals are user interfaces that interact with information and processes and consist ofone or more portlets. Portlets are displayed to end users on pages in a portal.

• WebSphere Portlet Factory (WPF) is a wizard-based development tool that facilitatesrapid portlet development.

• Builders, models, and profiles are the basic building blocks of WPF applications. Buildersare wizard-based interfaces that automate common development tasks. Models are collec-tions of builder calls. Models are often deployed as portlets to a portal server. Profiles areused to facilitate functionality based on different contexts, roles, or settings, and they canbe used to generate multiple copies of an application from the same code base.

Important Points 35

Page 73: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• When you open, save, or apply changes to a model, a WPF mechanism known as theFactory generation engine creates one or more executable versions of your model calledWebApps. WebApps consist of artifacts like Java code, HTML pages, and XML files,and are built according to the inputs in your builder calls.

• Portlet Factory applications can be packaged into three different types of WAR files: adevelopment WAR, a portlet WAR, and a deployment WAR. The development WAR con-tains artifacts that assist in the development process and must be deployed to an applica-tion server. The portlet WAR must be deployed to a portal server and can take advantageof the portal server’s functionality. Models in a portlet WAR that contain a PortletAdapter builder can be run as portlets. The deployment WAR cannot utilize portal func-tionality and does not contain the development artifacts included in the developmentWAR. Deployment WARs are useful for deploying non-portal applications to a produc-tion server and must be deployed to an application server.

36 Chapter 1 Introduction to WebSphere Portlet Factory

Page 74: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

37

C H A P T E R 2

Providing andConsuming Services

Service Oriented Architecture (SOA) is becoming an increasingly prevalent part of portletdesign. A pattern I will refer to as the “service provider/consumer pattern” is employed to imple-ment SOA in WebSphere Portlet Factory applications—in this chapter, you learn what this pat-tern is and how to use it. You also use the pattern to build a simple portlet that retrieves a staffroster, and you learn about how you can stub services to help test your portlets. By the end of thechapter you will understand the advantages provided by the service provider/consumer pattern,and you will be able to implement it effectively in other scenarios.

The files used in this chapter are available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 2 folder (instructions for copying these files into your projectare included in a readme.txt file in the same folder); however, to increase your understanding ofthe topics discussed, it is recommended that you create these files yourself by following theexample in this chapter.

The following topics are covered in this chapter:

• The service provider/consumer pattern

• Creating a service provider

• Creating a service consumer

• Creating a stub service

• Applying the service provider/consumer pattern

The Service Provider/Consumer Pattern

In WPF applications, the service provider/consumer pattern is used to implement SOA, whichmakes your applications more modular and extensible. (For information on some of the termsused in discussing this pattern, see the sidebar “Service Terminology.”) Applications built using

Page 75: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

the service provider/consumer pattern are loosely coupled; this means that the services that theyconsist of can be modified with little or no effect on the rest of the applications. For example, aservice connecting to a SQL server database can be modified to connect to a DB2® database with-out needing to modify design elements that interact with the service. Services in WPF applica-tions can do anything from retrieving and updating employee data to running sales reports. Ingeneral, services are usually employed to model high-level business processes, and often inte-grate with backend data sources or other applications.

The service provider/consumer pattern consists of a service provider, which provides a ser-vice to one or more service consumers. The functionality of the service is defined through one ormore functions or operations, which are then executed or consumed by the service consumer. Aresult is then usually returned back to the consumer and displayed on the screen. In WPF, thisprocess is normally achieved by using separate models for the service consumer and serviceprovider, so that you can then modify the service provider without needing to modify the con-sumer. Figure 2.1 shows a diagram of the relationship between the service provider and serviceconsumer.

38 Chapter 2 Providing and Consuming Services

ServiceProvider Model

Operation 1

Operation 2

ServiceConsumer Model

Service Call 1

Service Call 2

ServiceConsumer Model

Service Call 2

Figure 2.1 The service provider/consumer pattern.

In the first part of this chapter, you build a service provider model to provide a staff rosterservice. The service will contain a single operation, which retrieves the roster from an XML vari-able. The roster consists of a five-day working week, with each day assigned to a particular staffmember. In the later section of the chapter, “Creating a Service Consumer,” you add anothermodel to the project and surface it to a portal server as a portlet. This portlet will consume theoperation provided by the service provider and display the roster to the screen. The “Creating aStub Service” section discusses how you can test your services with stub data, and the final

Page 76: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

section of this chapter provides suggestions for applying the service provider/consumer pattern inother scenarios.

SERVICE TERMINOLOGY

A number of standard terms are used when discussing services. These are defined asfollows:

Service—A reusable component that performs specific functions on behalf of consumers.They are usually platform independent, and are loosely coupled to each other and to theapplication(s) calling the service. Services are black boxes in that consumers do not knowanything about how they work, but only about the function the services provide and the for-mat of the data to be sent to and from the services. Services are most commonly used inWPF to retrieve or update data in a backend data source, but they can also be used to doanything from finding out the weather to processing online forms.

Service Oriented Architecture (SOA)—A broad term used to denote the planning or endresult of employing services in systems and applications. Using an SOA promotes compo-nent reuse at a higher level of abstraction than that normally used in ordinary classes andfunctions. An SOA is generally more flexible than traditional architectures (in that modifica-tions or extensions to a component in an SOA have minimal impact on the rest of thesystem).

Operation—Services provide one or more operations, which form the interface used byconsumers to interact with the service. Operations sometimes define input and output vari-ables, which the consumer then uses to communicate with the service. The example in thischapter contains one operation, retrieveRoster, which is used by consumers to get accessto a staff roster. This operation takes no input variables (to retrieve the roster; it is enough tosimply call the operation) and returns an XML roster to the consumer of the service.

Service provider—Refers to a method, model, or application that offers a service. Theexample in this chapter contains a single provider: a model called rosterService, which pro-vides access to a staff roster stored in an XML variable.

Service consumer—Broadly used to denote a method, model, or application that calls (orconsumes) an operation on a service. The example in this chapter contains one consumer:a model called roster that consumes the retrieveRoster operation and then displays theresults (a staff roster) to the screen in a portlet.

Web service—A special type of service used over a network. Chapter 9, “Using Web Ser-vices and Manipulating XML,” walks through an example application that explains how toprovide and consume Web services in WPF.

Creating a Service Provider

Before you proceed with this section, you should be sure you have a WPF project that can be usedto contain the service provider model and service consumer model that you create in this chapter.If you have a project from Chapter 1, “Introduction to WebSphere Portlet Factory,” or from

Creating a Service Provider 39

Page 77: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

another chapter if you are not reading them in order, you can use it; otherwise, you should createa new WPF project (see Chapter 1 for more information on how to do this). The project will bepublished as a WAR file and deployed to a portal server, and you should also deploy the applica-tion to a local application server for testing. You can use the portal server if it is running on yourlocal machine; otherwise, it is recommended that you use the IBM WebSphere ApplicationServer Community Edition server (WAS CE) that comes with WPF.

After you have a project set up, you need to add a model to the project for your serviceprovider. This model uses the following builders to provide its functionality:

• Service Definition

• Variable

• Simple Schema Generator

• Action List

• Service Operation

These will be built and discussed in this order. In the example in this chapter, the ActionList, Simple Schema Generator, and Service Definition builders must precede the Service Opera-tion builder call; otherwise, you will receive errors in the Problems view, indicating that certainresources could not be found.

WARNING

Although the order of builder calls is usually not important, occasionally the order of yourbuilder calls can create errors or warnings in your application. These can occur when youtry to access the results of another builder call when that builder call has not yet generatedits associated code. Although you will not normally run into problems here, as a best prac-tice, you should always list referenced builder calls before the builder calls that referencethem. If you’re not sure what order to put your builder calls in, just keep an eye on the Prob-lems view, as any error or warning messages associated with builder call order will show upthere as soon as you add a builder call in the wrong place. These messages will be similarto “…is not available,” “…does not exist,” or “…did not evaluate to any fields.”

Creating a Model

Create a new model called rosterService in your project, under the folder WEB-INF/models/chapter02. The model should be based on the Empty template, which creates a model in yourproject that contains no builder calls. Note that the New Model Wizard has an option to create aDatabase Service Provider; you will use this option in Chapter 3, “Using Data from a RelationalData Source,” to create a service provider for accessing and manipulating a relational data source.For more information on creating models, see the example in Chapter 1.

40 Chapter 2 Providing and Consuming Services

Page 78: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Defining the Service

You now need to add some functionality to the rosterService model. To do this, first add a ServiceDefinition builder call to the model by selecting Service Definition from the Builder Palette (youcan open the Builder Palette by clicking the icon in the Outline view) and pressing OK.

After you have a service definition builder call, fill in the settings in the Model Editor, asshown in Figure 2.2. Note that the Make Service Public option is checked, which makes the ser-vice accessible to the consumer model you will create in the next section. Notice the GenerateWSDL option is not enabled. WSDLs are used for communicating with Web services, and youcan enable this option to enable your service as a Web service. Web services are discussed inChapter 9, “Using Web Services and Manipulating XML.” Note also that the Add Testing Sup-port option and Generate main options are checked. Together, these options add test pages to yourmodel (which you will use to test the operation on your service that you create later) and add amain action list. Note that every model that has an action list called main (usually added via theuse of the Action List builder) is directly executable. In this case, then, checking the main optionenables you to access the automatically generated service test pages by running the rosterServicemodel. (Note, however, that the main action list is created behind the scenes so you won’t be ableto actually see it in Outline view.)

When you are done entering the appropriate settings, press Ctrl+S to save the builder call.

Creating a Service Provider 41

Figure 2.2 Configuring the Service Definition builder call.

Page 79: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Roster Data

The next step is to add the roster that is retrieved by the service. There are a number of ways to dothis; in this example, you create an XML variable, and then generate a schema based on this vari-able, using a Simple Schema Generator builder call. The schema defines the structure of the dataretrieved from the retrieveRoster operation (you create the operation a little later). You can do thisin reverse as well; that is, create the schema first and then generate the XML data based on theschema (created with a Schema builder call). The first approach is useful if you don’t know howto write XML schemas (or you don’t have an XML schema authoring tool), because WPF willwrite the schema for you.

Add a Variable builder call to the model and change the builder call’s name to roster-Data. Display the Choose Variable Type dialog by pressing the … (ellipsis) button next to theType input. After the Choose Variable Type dialog is open, select XML and press OK. In the Ini-tial Value field, type in the XML shown here:

<Week xmlns=”http://com.ibm.serviceExample”>

<Monday xmlns=””>Bob</Monday>

<Tuesday xmlns=””>Sam</Tuesday>

<Wednesday xmlns=””>Sally</Wednesday>

<Thursday xmlns=””>Fred</Thursday>

<Friday xmlns=””>Greg</Friday>

</Week>

This XML document defines elements for a five-day week, and it also assigns a staff mem-ber to each day. The xmlns attribute of the Week element defines a namespace for the XML,which differentiates the Week element from Week elements in other namespaces.

In the Advanced section of the Variable builder call, select ‘Read-only: shared across allusers’ for the State and Failover input, and then save the builder call. By default, separate vari-ables are created in memory by the Variable builder for each user, so changing this setting ensuresthat only a single roster variable is used across all users. This setting also ensures that the variableis stored and recovered in the event that the application fails.

Add a schema to your model by selecting Simple Schema Generator from the BuilderPalette, and then press OK. Enter the name getRosterSchema for the schema, and type thename rosterData into the Sample Data field so that the rosterData Variable will be used as thebasis for the schema. Save the builder call when you are finished.

After the builder call is saved, a schema called getRosterSchema is automatically createdfor you and available to use in other builder calls in the model (you will link to the schema laterfrom a Service Operation builder call to define the structure of the roster). Note that every timeyou make a change to the structure of the rosterData Variable builder call, the schema getRoster-Schema is updated accordingly (alternatively, if you want changes to the Variable builder call tobe restricted to the structure specified in the schema, you should use a Schema builder call ratherthan the Simple Schema Generator).

42 Chapter 2 Providing and Consuming Services

Page 80: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding an Action to Retrieve a Roster

The next step is to create an Action List builder call. This builder call defines a series of actions toperform for the service operation getRoster. Add an Action List builder call by selecting ActionList from the Builder Palette in the Outline view and then pressing OK. Name the Action ListreturnXMLRoster. The Action List performs one simple action: It returns the value of the XMLroster to the calling function (in this case, it is the consumer of the getRoster operation).

To add this action, open the Select Action dialog by pressing the ellipsis button next to thefirst action in the action list. From the Select Action dialog, select Return from under the Specialfolder. In the Set Return Value dialog that follows, press the ellipsis button to bring up the ChooseReference dialog. Select Week from the Variables/rosterData folder, as shown in Figure 2.3, andthen press OK. This specifies that the data you would like to return is in the variable created bythe Variable builder you added earlier. The appropriate action now displays in the Set ReturnValue dialog. Press OK to return to the action list.

Creating a Service Provider 43

Figure 2.3 Specifying a return value in the Choose Reference dialog.

The last step for the action list is to change the return type of the Action List builder toIXml. IXml is an interface used by WPF to interact with XML. When working with XML vari-ables in WPF, you should always use the IXml type because there is no XML type as such. Forinformation on how to manipulate XML using the IXml interface, refer to the example in Chapter9, “Using Web Services and Manipulating XML.” Save the builder call when you are finished.

Adding a Service Operation

The final builder call to add to your service provider is a Service Operation builder call. Serviceoperations are the interfaces used by consumers to communicate with your service. In thisexample, you add only one service operation to your service, called getRoster. This operationcalls the action list you created earlier, which then returns the roster to the caller of the operation.

Page 81: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The reason why you need both a Service Operation builder call and an Action List builder call isbecause the Service Operation builder call can only link to other methods or action lists; youcan’t perform the ‘return’ function directly from the Service Operation builder call.

Add a Service Operation builder call by selecting Service Operation from the Builder Paletteand pressing OK. Fill out the Service Operation Properties section of the Service Operationbuilder call as shown in Figure 2.4. This declares that the operation is part of the rosterServiceservice, is called getRoster, and will run the action list returnXMLRoster when consumed. Theoperation description allows you to see what the operation does when linking to it in a ServiceConsumer model.

44 Chapter 2 Providing and Consuming Services

Figure 2.4 Configuring the Service Operation builder.

Next you must define what consumers of the service need to send to the operation (Opera-tion Inputs) and what they will receive in return (Operation Results). No inputs are required, sochange the Input Structure Handling input under the Operation Inputs heading to ‘No inputs.’Under the Operation Results heading, select the Specify Result Schema option to explicitly spec-ify a schema for the results, then type in getRosterSchema/Week for the Result Schema input.Type Five day roster for the Result Description, and make sure the Result Field Mappinginput is set to Automatic. This will automatically map the results of the operation into the Weekelement of the roster schema you created earlier.

Save the builder call when finished. You have now successfully created and configured yourservice provider model, which you will test in the next section.

Testing the Service Provider

Now that you’ve finished creating your service provider, you can test to see if the getRoster oper-ation is working correctly. Because you enabled testing support in the Service Definition buildercall, WPF automatically embeds testing facilities into the rosterService model for you.

To test the service, run the rosterService model from the WPF Designer by clicking the icon on the toolbar. This runs the currently active model (rosterService) with the last run configu-ration you used. If you have not set up a run configuration before, you will be prompted to do

Page 82: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

so—create a new configuration under the WebSphere Portlet Factory Model category. (If youwant more information on setting up a run configuration, see the “Testing the Application” sec-tion in Chapter 1.)

After you run rosterService, you should see the index test page in your default Webbrowser; it should be similar to the image shown in Figure 2.5. This screen lists all of the opera-tions available on the rosterService service.

Creating a Service Consumer 45

Figure 2.5 Index test page from the rosterService model.

To test the getRoster operation, click the getRoster link. You should see the roster dis-played, as shown in Figure 2.6. If not, check that you don’t have any errors showing in the Prob-lems view, and make sure you have changed the Return Type field on the Action List to IXml(otherwise, you will see only a blank table when you test the getRoster operation).

Figure 2.6 Testing the getRoster operation.

At this stage, you have a WPF project that contains a service provider model called ros-terService. The next section outlines how to build a service consumer model to consume the get-Roster operation and display the results in a portlet.

Creating a Service Consumer

This section describes how to add a second model to your project, which consumes the getRosteroperation provided by the rosterService model. The consumer is surfaced to a portal server as aportlet and displays the roster returned from the service operation (a screen shot of the portlet isshown in Figure 2.8, which appears later in the chapter).

There are two ways you can create service consumers in WPF: The first is to use the Listand Detail Service Consumer option in the new model wizard, and the second is to create the ser-vice consumer manually. A list in WPF is a collection of basic data across one or more records(usually displayed in a table or chart), whereas detail is data specifically related to a single record

Page 83: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

(which usually contains data not available in the list). The List and Detail Service Consumeroption give you everything you need in this example.

The service consumer model in this section uses the following builders to provide itsfunctionality:

• Portlet Adapter

• Service Consumer

• View & Form

These are added automatically using the WPF New Model Wizard.

Creating a Model

Start the New Model Wizard (select File, New, and then select WebSphere Portlet Factory Modelfrom the WPF Designer menu), and then specify the WPF project containing your serviceprovider on the next screen. Press Next. On the next screen, select the Detail Service Consumeroption for the model template and press Next.

The List and Detail Service Consumer automatically surfaces your model as a portlet via aPortlet Adapter builder call. Type the name of the portlet on the next screen as roster (this namewill also be used to name the other builder calls in your model). Also, specify the service providerchapter02/rosterService that you created in the previous section. Press Next when you arefinished.

TIP

It’s a good idea not to use the word ‘portlet’ in your model names, as you may decide toremove the portlet functionality later (or add it back in), and you don’t want to have torename all of the elements in your model every time this happens.

You can now specify the service operation that is used to provide your list data (forinstance, the roster). Select getRoster and press Next. The next screen contains settings for thedetail part of the data. There is no detail data in this example, as you are displaying only the list(the roster), so deselect the ‘Create link to details’ checkbox. Using the detail option is describedin Chapter 3, “Using Data from a Relational Data Source,” and Chapter 4, “Using Domino Data.”Press Next to continue.

Give your model the name roster, and then store the model in the models/chapter02folder. This is the name of the model as it is in the IDE. Note that although the model name andportlet name are the same in this example, it is possible to use different names for each field. Whenyou are done, press Finish to build your model. This creates a new model called roster in yourproject and opens the model in the Model Editor and Outline view. The roster model contains threebuilder calls: a Portlet Adapter, a Service Consumer, and a View and Form. The Portlet Adapter

46 Chapter 2 Providing and Consuming Services

Page 84: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

builder converts the model into a portlet that can be viewed inside a portal. (Note that if you makeany changes to this builder call—including the changes you are about to make—you need torebuild the deployed application before you can see the results of the changes. For more informa-tion on this process, see the example in Chapter 1). The Service Consumer builder consumes theoperation getRoster on the rosterService service, and the View and Form builder displays any listand detail data in the model to the screen. The View and Form builder contains a number ofoptions for manipulating how the data is displayed; although these options are discussed in thischapter, they are covered in more detail in Chapter 5, “Customizing Portlet Appearance.”

Configuring the Portlet Adapter

The builder calls don’t require any configuration in this example, except for two small changes tothe Portlet Adapter builder call. Open the Portlet Adapter builder call and change the Portlet Titleto Roster and change the Portlet Description to This portlet displays the staff ros-ter to the screen. Save the builder call when you are finished. The Portlet Title identifies theportlet inside the portal (it is actually displayed in the title bar of the portlet), and the PortletDescription displays on various administration screens inside the portal.

TIP

Note that the Portlet Title is blank by default, so any time you use the List and Detail Ser-vice Consumer option when creating a new model (or, any time you add a Portlet Adapterbuilder to a model), be sure you enter a value for the Portlet Title field. If you leave thePortlet Title field blank, the name of the model will be used for the portlet title (which isusually undesirable).

Your project now contains a service provider model and service consumer model. The ser-vice provider provides a service called rosterService with a single operation called getRoster. Theservice consumer should be able to consume the operation and display the results (a roster) to thescreen, which you test in the next section.

Testing the Service Consumer

To test your service consumer from the WPF Designer, make sure the roster model is the cur-rently active model in the Model Editor (for instance, check that you haven’t closed it or switchedback to editing the rosterService model). Run the roster model from the WPF Designer, and youshould see the roster display in your default Web browser, as shown in Figure 2.7.

After you have tested the service consumer model, you should rebuild the application andtest it on the portal server as a portlet (for instructions on how to do this, see the example in Chap-ter 1). After you have added the portlet to a page in the portal, your portlet should display asshown in Figure 2.8.

Creating a Service Consumer 47

Page 85: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 2.7 Testing the roster model.

48 Chapter 2 Providing and Consuming Services

Figure 2.8 The Roster portlet.

Creating a Stub Service

A stub service is a service that contains dummy data. You normally use a stub service when youare accessing or manipulating data in a backend data source, and the data source is not readilyavailable (for example, perhaps you are developing in a test environment that cannot authenticatewith the data source). When stubbing a service, you normally create a stub model, which is basi-cally a copy of your service provider model that contains dummy data (and doesn’t require con-nectivity to the data source).

You can create a stub model using inputs in the Interface and Stub Models section of theService Definition builder, shown in Figure 2.9 (you can also create a stub model via a ServiceStub builder call, which contains the same options provided by the Interface and Stub Modelssection of the Service Definition builder). The Interface Model can be used to specify a serviceinterface, which you use when you have multiple service models that have a common interface(with the same operations), and the Stub Model input is the name and location of your stubmodel. Pressing the Generate Stub Model button regenerates the stub model specified in the StubModel input.

Page 86: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 2.9 Service stub options on a Service Definition builder call.

There is no need to use a stub service in the example in this chapter because you are notlinking to a data source, and the data (the XML roster) is always readily available. For an exampleusing a stub service, see Chapter 4, which discusses how to stub a Lotus Notes database, whichwill enable you to test the service even when you don’t have connectivity to a Domino server.

Applying the Service Provider/Consumer Pattern

The service provider/consumer pattern demonstrated in this chapter can (and should) be usedthroughout your WPF applications, as it provides you with powerful features such as caching,inbuilt testing capabilities, and stub support. However, this is not to say that every single methodin your applications should be accessed through a service. When considering a function as apotential candidate for a service, you should consider whether you will actually gain from pro-viding the functionality through a service. Simple functions with limited potential for reuse arepossible scenarios in which a service provider and consumer might actually make an applicationmore complicated than it needs to be. Having said this, service provider and consumer modelsclearly delineate and separate functionality in the model tier of an application from the view tier(if you are unfamiliar with these terms, see the following sidebar “The Model View ControllerPattern”), which can make your applications clearer and easier to maintain.

THE MODEL VIEW CONTROLLER PATTERN

The Model View Controller (or MVC) pattern is a commonly employed pattern in J2EE devel-opment, which separates out an application into three separate divisions (or tiers). In WPF,the content of these tiers can be contained in anything from a builder call, to a Java class, toan HTML file. Builder calls from different tiers are normally separated into different models,and these models are sometimes even stored in different subdirectories of the models folderfor clarity.

Model—A model is the data or business logic in an application (not to be confused with themodel that is a collection of builder calls in WPF). WPF does not offer rich functionality formanipulating business logic out-of-the-box, so complicated business logic is sometimesfarmed out to an external Java method and then accessed from a Linked Java Object builder

Applying the Service Provider/Consumer Pattern 49

Page 87: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

or Service Consumer builder (for more information on using Java in WPF, refer to Chapter 8,“Using Java in Portlets”). Data in WPF is usually accessed and manipulated via a ServiceConsumer builder.

View—A view is the user interface of your application (HTML pages, UI controls, and so on).In WPF, many of the elements in the view tier are stored in the WebContent/factory directory,such as HTML templates and style sheets. Other custom controls (such as those added byButton and Page builder calls) are usually stored in their own “view” model. The view tier isalso sometimes referred to as the presentation tier.

Controller—A controller is a method that controls the execution flow in an application. Themain action list is an example of a controller in WPF, as is the Factory controller servlet men-tioned in Chapter 1.

You should also consider what the candidate function actually does. Services usuallymodel higher-level functions or processes than traditional classes or modules, and often corre-spond directly with a particular business function or process (although this doesn’t necessarilyhave to be the case). So, for example, you might use the service provider/consumer pattern tohandle some of the following functionality and processes:

• Accessing or manipulating a backend data source (for example, updating a LotusDomino database).

• Kicking off a business process (for example, lodging an application form).

• Calling a shared Java method, EJB call, or Linked Java Object (LJO).

• Performing business logic (for example, deciding if a customer is eligible for a specialoffer).

Note that the example in this chapter can also be built without using the service provider/consumer pattern because the service just runs an action list that returns the value of an XMLvariable. However, using a service here provides a number of advantages: It clearly separates themodel and view tiers of your application; it removes several builder calls from the service con-sumer model, making it clearer; any future models in the same application will be able to use therosterService service as well; and any future modifications to the rosterService service will notrequire changes to the roster model (provided that the name of the service operation doesn’tchange and the schema it uses remains intact). As a general rule, if a function is to be accessedfrom several models or if it provides some business function or process, it is usually a good ideato employ the service provider/consumer pattern. In the context of the example in this chapter,then, potential extensions could include a setRoster operation to the rosterService service, so thata roster manager can change the roster, or a sendRoster operation, which might email the roster toa division manager.

50 Chapter 2 Providing and Consuming Services

Page 88: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Summary

In this chapter, you learned how to create service providers, consume a service from a portlet, andbuild applications in WPF based on the service provider/consumer pattern. This pattern is anexcellent way to build applications in WPF because it helps keep your applications modular andseparates your model tier from your view tier. You also created, deployed, and tested an applicationbased on this pattern, which contained a service provider model and a service consumer model.The service consumer model was surfaced to a portal server as a portlet. You also learned aboutservice stubs and potential scenarios in which the service provider/consumer pattern can be used.

The next chapter, “Using Data from a Relational Data Source,” describes how to use theservice provider/consumer pattern to interact with a relational data source from a portlet.

Important Points

• The service provider/consumer pattern is used extensively in WPF applications, particu-larly to interact with backend systems. Using the service provider/consumer patternencourages separation of the presentation and model tiers in an application.

• A service provider is a design element (usually a model) used to offer shared, high-levelfunctionality to one or more applications. This functionality is offered through a seriesof operations on the service provider.

• A service consumer is a design element (such as a model) that calls the operations on aservice provider.

• The Service Definition and Service Operation builders are normally used to create a ser-vice provider model. The service in this model is then usually consumed via a ServiceConsumer builder.

• The Simple Schema Generator builder can be used to automatically generate XMLschemas from an XML document in WPF.

• Stub services are services that contain dummy data and are often used in WPF to testdata services when there is no connectivity to a database.

Important Points 51

Page 89: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 90: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

53

C H A P T E R 3

Using Data from aRelational DataSource

One of the most common uses for WebSphere Portlet Factory (WPF) is to surface functionalityfor interacting with relational data through a portlet. The subject of this chapter is how you canuse some of the default WPF builders to perform basic data operations on a relational data sourceand provide this functionality through a portlet. By the end of this chapter, you will understandhow to use the WPF builders to access and manipulate a relational data source, and you will havebuilt a sample contact portlet to demonstrate this functionality. Each of the files in this chapter isavailable for download from ibmpressbooks.com/title/9780137134465 under the Chapter 3folder (instructions for copying these files into your project are included in a readme.txt file in thesame folder); however, to increase your understanding of the topics discussed, it is recommendedthat you create these files yourself by following the example in this chapter.

Before you begin the example in this chapter, you need to create the contact database towhich the portlet will connect. Appendix A, “Setting Up Your Environment,” gives instructionsfor creating the contact database on either a DB2 or SQL Server.

The following topics are covered in this chapter:

• Using data services

• Creating a service provider

• Creating a contacts portlet

Using Data Services

Data from a backend data source is normally accessed and manipulated via a service providermodel, which users interact with through a service consumer. The service consumer model isoften surfaced to a portal server as a portlet (for more information on this pattern (and services ingeneral) refer to Chapter 2, “Providing and Consuming Services”).

Page 91: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

In WPF, data from a service provider is retrieved in two parts: a list (sometimes called aview) and detail. In the context of a relational data source (such as an SQL server database orDB2 database), a list is a snapshot of records from a table, and the detail is an individual row inthe table. A list usually contains only select information about each record (contact name, com-pany, and phone number, for example), whereas the detail often provides more in-depth informa-tion (such as address, contact email, and fax number).

WPF offers several out-of-the-box builders to facilitate this functionality, including numer-ous UI builders and backend connectivity builders. In this chapter, you use some of these buildersto create a service provider model for accessing contact data (first name, last name, company,address, phone number, email, and fax number) in a relational database. The service providesseveral operations, which let users create, read, update, and delete records in the database. Theseoperations are consumed from a service consumer model, which are surfaced to a portal server asa portlet.

Creating a Service Provider

In this section, you build a service provider model to provide access to the contact data in theTESTDB database. Note that before you proceed with this section, you need to set up theTESTDB database as outlined in Appendix A. Also, you need a WPF project, which can housethe service provider model (and the contacts portlet that you create later). If you have a projectfrom a previous chapter, you can use it; otherwise, you should create a new WPF project (formore information on creating projects, see Chapter 1, “Introduction to WebSphere Portlet Fac-tory”). The project will be published as a WAR file and deployed to a portal server, and youshould also deploy the application to a local application server for testing. You can use the portalserver if it runs on your local machine; otherwise, it is recommended that you use the IBM Web-Sphere Application Server Community Edition server (WAS CE) that comes with WPF.

After you have a project set up, you need to add the service provider model. This modeluses the following builders to provide its functionality:

• Service Definition

• SQL Call (x5)

• Service Operation (x5)

These are added automatically using the WPF new model wizard.

Creating a Model

Open the new model wizard by selecting File, New, WebSphere Portlet Factory Model from theFile menu. When the dialog appears, select your WPF project and press Next. You then see a listof different types of models that WPF can create for you automatically. You can create serviceproviders in WPF in two ways: The first is to let WPF create one for you (which you can do byusing the Database Service Provider option in the Select Model wizard), and the second is to

54 Chapter 3 Using Data from a Relational Data Source

Page 92: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

create the service provider manually. The Database Service Provider option is a useful shortcut ifyou are connecting to a backend database, because it automatically populates your model withuseful builder calls, and the manual option is useful if you want to use builder calls other thanthose populated by the wizard. Select the Database Service Provider option and press Next.

Defining the Service

The next screen enables you to define the service. Give the service the name contactsService.If you enable the Generate WSDL checkbox, a WSDL document is automatically created foryour service, enabling it as a Web service. The Generate WSDL checkbox can also be found onthe Service Definition builder call, so you can enable or disable your service as a Web service atany time (Web services are discussed in Chapter 9, “Using Web Services and ManipulatingXML”). Leave the Generate WSDL checkbox unchecked and press Next.

Specifying the First Operation

You can now specify the first operation for the service. You will define five operations in thisexample: one to retrieve a list of contacts, one to retrieve details for an individual contact, one tocreate a new contact, one to update an existing contact, and one to delete a contact. The first oper-ation enables you to read details on a particular contact.

In the SQL DataSource field, specify the TESTDB data source (jdbc/TESTDB). If this datasource does not display, make sure you have completed the “Configuring a JDBC Resource” sec-tion in Appendix A. Also, check to see that you have restarted the application server after addingthe data source.

In the SQL Statement field, specify the following SQL statement:

SELECT ID, FIRSTNAME, LASTNAME, COMPANY, PHONE FROM

“ADMINISTRATOR”.”CONTACTS”

This SQL retrieves a list of records from TESTDB, but displays only the ID, FIRSTNAME,LASTNAME, COMPANY, and PHONE columns (so that the list is easier to read). Press Nextwhen finished.

On the next screen, type getContactsList as the Operation Name and select ‘Multiplerows’ for the Operation Returns input. Make sure the ‘Create another operation’ checkbox isenabled. These settings define the name of the operation as it displays to consumers and ensuresthat multiple rows are returned from the operation. Also, the ‘Create another operation’ checkboxdeclares that you would like to create more operations for the service, which causes the wizard toprompt you for more operation details on the next screen. Press Next to continue.

Specifying the Second Operation

Now, create the second operation. Select jdbc/TESTDB for the SQL DataSource input as before,and then type the following SQL into the SQL Statement input:

SELECT * FROM “ADMINISTRATOR”.”CONTACTS” WHERE ID = ?

Creating a Service Provider 55

Page 93: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This SQL returns every column (ID, FIRSTNAME, and so on) for a particular contact,where the ID matches the value of a certain parameter. This information is eventually displayedfrom the service consumer when a user clicks on a particular ID. Press Next when you are fin-ished. Notice the use of the ? symbol—this is used in WPF to denote the value of a parameter,which you will now define.

Fill in the options on the next screen, as shown in Figure 3.1 (but don’t press the Next but-ton yet). For this operation, only a single row is returned. Notice the contents of the OperationInputs section; this defines the name of the ‘?’ parameter. An ID is passed to the operation when itis called, which is then used to retrieve details for that particular contact. When you’ve filled outthis screen so that it appears as shown in Figure 3.1, enable the box to create another operation(the ID column might disappear depending on the version of WPF you are using, but this won’taffect the operation). Press Next when you are finished.

56 Chapter 3 Using Data from a Relational Data Source

Figure 3.1 Configuring the second service operation.

Specifying the Third Operation

You can now specify a third operation. Select jdbc/TESTDB for the SQL Datasource, and thentype the following SQL as a single line into the SQL Statement input:

Page 94: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

INSERT INTO “ADMINISTRATOR”.”CONTACTS” (FIRSTNAME, LASTNAME,

COMPANY, ADDRESS, PHONE, EMAIL, FAX) VALUES (?,?,?,?,?,?,?)

This SQL creates a new contact with the values of the parameters passed in. (Note: There isno need to set the ID column, as it is automatically generated.) Press Next when you are finished.

Fill out the next screen as shown in Figure 3.2, and then press Next. Checking the ‘Createanother operation’ box locks the parameters in and prevents you from editing them, so make sureyou check this box after you have entered in the parameters. Note that there is no need for outputfrom this operation, as the operation simply updates the TESTDB database. In addition, the orderof the parameters is important—as specified in the SQL call, the value of the first parameter isassigned to the FIRSTNAME column, the second is assigned to LASTNAME, and so on.

Creating a Service Provider 57

Figure 3.2 Configuring the third service operation.

Specifying the Fourth Operation

To enter the fourth operation, select jdbc/TESTDB for the SQL Datasource, and then type the fol-lowing SQL line into the SQL Statement input:

UPDATE “ADMINISTRATOR”.”CONTACTS” SET FIRSTNAME = ?, LASTNAME

= ?, COMPANY = ?, ADDRESS = ?, PHONE = ?, EMAIL = ?, FAX = ?

WHERE ID = ?

Page 95: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This SQL updates an existing contact with the values of the parameters passed in for a con-tact with the ID specified. (Note: There is no need to set the ID column, as it was automaticallygenerated when the contact was created and there is no need to change it.) Press Next when youare finished, and then fill out the next screen, as shown in Figure 3.3. Press Next when you are fin-ished. The order of parameters on this page is important.

58 Chapter 3 Using Data from a Relational Data Source

Figure 3.3 Configuring the fourth service operation.

Specifying the Fifth Operation

You can now specify the fifth and final operation on the service. Select jdbc/TESTDB for theSQL Datasource, and then type the following SQL into the SQL Statement input:

DELETE FROM “ADMINISTRATOR”.”CONTACTS” WHERE ID = ?

Page 96: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This SQL deletes an existing contact from TESTDB that matches the ID specified in theparameter. Press Next when finished, and then fill out the inputs on the next screen, as shown inFigure 3.4. Press Next when you have filled out the appropriate inputs.

Creating a Service Provider 59

Figure 3.4 Configuring the fifth service operation.

Give your model the name contactsService and make sure it is created in the directorymodels/chapter03. Press Finish to build your model. This creates a new model called con-tactsService in your WPF project and opens the model in the Model Editor and Outline view.

You have now finished creating your service provider, which you will test in the next sec-tion. Spend a few minutes exploring the builder calls WPF has automatically added to the con-tactsService model. The Service Definition builder call defines general properties for the entireservice, and a Service Operation and SQL Call builder call have been added for each operationspecified in the WebSphere Portlet Factory Model wizard. The SQL Call builder is discussed inthe following sidebar, “The SQL Call Builder.”

Page 97: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

THE SQLCALL BUILDER

Several low-level SQL builders are available in WPF. That is, they are builders used for aspecific purpose, as opposed to high-level builders which amalgamate functionality fromseveral other builders. The SQL DataSource builder, for example, is used to connect to arelational data source, and the SQL Statement builder is used to execute an SQL statementon a relational data source. The SQL Call builder used in this chapter is a high-level builderthat amalgamates the key functionality of these other SQL builders.

The top section of the SQL Call builder enables you to specify a link to a JDBC resource.Any data sources you connect to need to have the jdbc/ prefix to get picked up by WPF. Theother inputs on the page are used to configure the data source specified in this section.

The Database Explorer section of the builder can be used to browse tables and storedprocedures in a database, which can then be used to generate SQL statements.These SQLstatements can be copied into the middle section of the builder, which is used to store aSQL statement that can be executed from other builders. For example, in this chapter, theSQL specified in the middle section of each SQL Call builder is executed via operations onthe service provider. Note that when using the SQL inputs on the builder, there is no need touse the escape character \ in front of quotes—just type in the quotes directly (as in theexample).

The Result Set Handling section defines characteristics of the results returned from theSQL statement specified in the SQL Statement input (if a SELECT statement was specified)and enables you to transform these results into an XML document. XML documents areused extensively in WPF, as they provide a simple and powerful mechanism for interactingwith data (manipulating XML in WPF is discussed in Chapter 9).

The Method Names section is used to specify custom names for the methods used tointeract with the SQL Call builder. This is useful if you want to rename methods for clarity orif you want the method names to conform to a coding convention.

The Events, Statistics, and Logging section enables you to log various events and statis-tics from the builder (logging in to WPF is discussed in Chapter 14, “Error Handling, Log-ging, and Debugging”).

The Builder Override Definition section can be used to override inputs in the SQL Callbuilder with inputs from other SQL builders.

Although the SQL Call builder provides most of the functionality you need when workingwith relational data sources, the other SQL builders provide several additional options thatyou might find useful in certain scenarios. For example, the SQL Statement builder enablesyou to specify the maximum number of rows to return for a SQL statement, which you can’tdo with the SQL Call builder.

Testing the Service Provider

By default, WPF automatically generates test pages for your service provider (which you can dis-able from the Testing Support section of the Service Definition builder call). This enables you totest the service provider directly from the IDE.

60 Chapter 3 Using Data from a Relational Data Source

Page 98: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

To test the service, run the contactsService model from the WPF Designer by clicking theicon on the toolbar. This runs the currently active model (for instance, contactsService) with

the last run configuration you used. If you have not set up a run configuration before, you areprompted to do so—create a new configuration under the WebSphere Portlet Factory Model cate-gory. If you want more information on setting up a run configuration, refer to the “Testing theApplication” section in Chapter 1.

After you run contactsService, you should see the index test page in your default Webbrowser, as shown in Figure 3.5. This screen lists all the operations available on the contactsSer-vice service.

Testing the Service Provider 61

Figure 3.5 Index test page from the contactsService model.

Testing the retrieveContactsView Operation

To test the getContactsList operation, click the getContactsList link. You should see a list of con-tacts, as shown in Figure 3.6. If not, ensure you don’t have any errors showing in the Problemsview in the IDE and ensure that you have completed all the steps in the previous section correctly.Also, make sure the connection to the TESTDB data source works on the application server (youcan test this from the administration console, which is described in the “Configuring a JDBCResource” section of Appendix A). Press Back to return to the index page.

Figure 3.6 Testing the getContactsList operation.

Page 99: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

If your data source is large (over 10,000 rows), it might be too slow to retrieve the entireresult set every time you access the data.You can cache your data by adding a Cache Con-trol builder to your model and pointing it to the result set.You can also perform partial fetchesusing the Service Operation Builder and display these results across several pages. Pagina-tion is discussed in more detail in Chapter 5, “Customizing Portlet Appearance.”

Testing the getContactDetail Operation

To test the getContactDetail operation, click the getContactDetail link. The screen that followsenables you to specify parameters for the operation. Enter 1 as the ID and press the Submit Querybutton. You should see details for the contact who has an ID of 1 (that is, Bob Jones), as shown inFigure 3.7. Press Back when you are finished. Note that in this example, no validation is used—validating data from an input screen is covered in Chapter 11, “Field Validation, Formatting, andTranslation.”

62 Chapter 3 Using Data from a Relational Data Source

Figure 3.7 Testing the getContactDetail operation.

TIP

If you open the Service Definition builder call and enable the Specify Default Inputs box inthe Testing Support section, you can specify default values for your testing so that you don’tneed to retype them every time. For example, if you type 1 for getContactDetailQueryIn-puts.ID field for the getContactDetail operation, this ID is used when testing the operationunless another ID is specified.

Page 100: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the createContact Operation

To test the createContact operation, click the createContact link. The screen that follows enablesyou to specify parameters for the operation, which are the values used to create the new contact.Enter in some sample data and press the Submit Query button.

When the screen reloads, it will display nothing but a Back button—press this to continue.If the contact was added correctly, you should be able to run the getContactsList operation againand see the new contact displayed at the bottom of the list.

Testing the setContact Operation

To test the setContact operation, click the setContact link. The screen that follows enables you tospecify parameters for the operation, which are the values used to update a particular contact.Enter in the ID of the contact you created in the previous step, in addition to some new data forthat contact, and press the Submit Query button. If the operation worked correctly, you should beable to run the getContactsList operation again and see that the contact is listed with the detailsyou just entered. Note: Although the test page requires you to reenter each field, these fields areautomatically populated when you edit a contact from the service consumer.

Testing the deleteContact Operation

To test the deleteContact operation, click the deleteContact link. Enter in the ID of the contactyou would like to delete (such as the ID of the contact you just created and updated), and thenpress the Submit Query button. When the screen reloads, it displays nothing but a Back button;press this to continue. If the contact was deleted correctly, you should be able to run the getCon-tactsList operation again and see that the contact has been removed. Close the contactsServicemodel when you’ve finished testing it.

You now have a service provider called contactsService, which provides create, read,update, and delete functions for the TESTDB database. The next section walks you throughcreating a service consumer model to consume the operations offered by this service and pro-vides an interface to these operations in a portlet.

Creating a Contacts Portlet

This section describes how to add a second model to your project, which defines a user interfaceto consume the various operations offered by your service provider. This service consumer modelis then surfaced to a portal server as a portlet. For more information on the service consumer/provider pattern in WPF, see Chapter 2, “Providing and Consuming Services.” Figure 3.21 laterin this chapter shows a screenshot of the finished portlet.

The service consumer model uses the following builders to provide its functionality:

Creating a Contacts Portlet 63

• Portlet Adapter

• Service Consumer

• View & Form

• Action List (x2)

• Comment (x2)

• Button (x2)

• Input Form

Page 101: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Note that the model developed in this section uses only basic display options; the focus ismore on consuming services that access and manipulate a relational data source. For more infor-mation on arranging output in portlets, see Chapter 5.

Creating a Model

To create the service consumer model, select File, New, WebSphere Portlet Factory Model fromthe File menu to bring up the WebSphere Portlet Factory Model dialog. On the next screen, selectyour WPF project and press Next. WPF then displays a list of different types of models that canbe created for you automatically. You can create service consumers in WPF in two ways: The firstis to let WPF create one for you (which you can do by using the List and Detail Service Consumeroption in the wizard), and the second is to create the service consumer manually. The List andDetail Service Consumer option gives you everything you need in this example, so select it in thewizard and press Next.

The List and Detail Service Consumer automatically surfaces your model as a portlet via aPortlet Adapter builder call. Specify the name of the portlet on the next screen as contacts (thisname will also be used to name the other builder calls in your model). Also, select the serviceprovider chapter03/contactsService you created in the previous section. Press Next when finished.

You are then required to specify the service operation that is used to provide the list of con-tacts. Select getContactsList and press Next to enter in the settings for the detail part of the data.Fill out the boxes, as shown in Figure 3.8, and press Next. This converts all of the values in the IDcolumn in the contact list into clickable links. When a user clicks on the link, the ID is passed tothe getContactDetail operation and the results displayed on the screen.

The next screen enables you to configure the value of the ID parameter to be sent to the get-ContactDetail operation. Accept the defaults and press Next. The default value for the ID param-eter takes the ID value from the contact clicked by the user. Finally, give your model the namecontacts and make sure it is created in the directory models/chapter03. This is the name of themodel as it appears in the IDE. Note: In this example, although the model name and portlet nameare the same, it is possible to use different values for each name. When you’ve entered the name,press Finish to build the model. This creates a new model called contacts in your WPF project andopens the model in the Model Editor and Outline view.

The contacts model contains three builder calls: a Portlet Adapter, a Service Consumer, anda View & Form. The Portlet Adapter builder converts the model into a portlet, which can beviewed inside a portal. (Note: If you make any changes to this builder call—including thechanges you are about to make—you need to rebuild the deployed application before you can seethe results of the changes. For more information on this process, see the example in Chapter 1.)The Service Consumer builder consumes the operation getContactsList on the contactsServiceservice, and the View & Form builder displays any list and detail data in the model to the screen.The View & Form builder also enables you to do some basic manipulation of how the data is dis-played (the View & Form builder is discussed in more detail in Chapter 5).

64 Chapter 3 Using Data from a Relational Data Source

Page 102: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Contacts Portlet 65

Figure 3.8 Specifying a detail operation.

Configuring the Portlet Adapter

The Portlet Adapter builder call requires two small changes before it can be used. Double-clickthe Portlet Adapter builder call to open it in the Model Editor, and then change the Portlet Title toContact and the Portlet Description to Interface for interacting with the TESTDBdatabase. Save the builder call when finished. The Portlet Title identifies the portlet inside theportal (it will actually be displayed in the title bar of the portlet), and the Portlet Descriptionappears on various administration screens inside the portal.

At this stage, the service consumer model is using only two of the five operations providedby the service provider—that is, you can read a list of contacts from TESTDB, and you can alsoview details on an individual contact by clicking on their ID. Preview the contacts model nowfrom your IDE, which will give you some understanding of what the wizard creates by default.

The next few sections describe how to surface functionality for the create, update, anddelete operations. Note that at the completion of each of the following sections, you can test yourchanges directly from your IDE.

Adding Update Functionality

To add functionality from the setContact operation, double-click on the View & Form builder callin the Outline view. Scroll down to the Update Page Support section, and then tick the CreateUpdate Page checkbox. Some new options appear underneath—fill out the Update Method and

Page 103: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Update Next Action inputs, as shown in Figure 3.9. Note that you don’t need to type these indirectly; you can select them from the Select Action dialog, which you open by clicking the ellip-sis button to the right of the builder input.

66 Chapter 3 Using Data from a Relational Data Source

Figure 3.9 Configuring update support on the View & Form builder.

The Update Method defines what happens when new data is submitted (it will run the set-Contact operation in this case), and the Update Next Action defines a post update action (in thiscase, the contactsView_ShowResults method created by the View & Form). The contactsView_ShowResults method is used to refresh the contacts list with any changes and redisplay the con-tacts list—something that is not done automatically. You don’t always need to define a postupdate action, but it can be useful if you want to perform additional actions after an update.

Save the builder call when finished.

TIP

The View & Form builder creates three pages in your model:

contactsView_ViewPagecontactsView_DetailsPage contactsView_UpdatePage

The name of the View & Form builder call is used as a prefix for each page. The ViewPagepage contains the contact list. The DetailsPage is the page used to display detail informa-tion on an individual contact, and the UpdatePage is the page used to edit a contact.Youcan place controls on these pages by specifying one of them in the Page input on a builderthat creates UI elements. Placing controls on pages is discussed in Chapter 6, “AddingBasic User Interface Controls to Your Portlets.”

An Edit button is now displayed on the detail page, which lets you edit the current contactand update the TESTDB database accordingly.

Adding Delete Functionality

To add functionality from the deleteContact operation, first add a Comment builder call to theservice consumer model. This comment isn’t strictly necessary, but it will help to organize yourmodel and make it clearer. Name the Comment Delete and save the builder call. Now, add

Page 104: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

another action list to the service consumer model. This action list will define what happens whena user wants to delete a contact. Name the Action List deleteContact, and then press the ellip-sis button next to the first action to open the Select Action dialog. The first action that you defineassigns the ID of the currently selected contact to the argument that is passed in to the delete oper-ation. Select Assignment as shown in Figure 3.10.

Creating a Contacts Portlet 67

Figure 3.10 Specifying the first action for deleteContact.

In the Make Assignment dialog that follows, press the ellipsis button next to the Target boxand select ID from the list of the deleteContact arguments, as shown in Figure 3.11. This specifiesthe argument that will be set.

Figure 3.11 Selecting the target value.

Page 105: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

68 Chapter 3 Using Data from a Relational Data Source

Next, press the ellipsis button next to the Source box and select ID from the currentlyselected contact, as shown in Figure 3.12. The value of this field is used to set the value of the tar-get ID specified in the previous step. Press OK when you are finished.

Figure 3.12 Selecting the source value.

For the second action in the action list, select deleteContact from the Select Action dialog(it then appears in the Action List as DataServices/contacts/deleteContact). This actually calls thedeleteContact operation, passing in the value of the parameter that was set in the previous step.Press OK when you are finished.

For the third action in the action list, select contactsView_ShowResults from the SelectAction dialog. This is the method created by the View & Form builder that refreshes the contactslist after the delete operation is performed, and then returns the user to the contacts view. PressOK when finished and save the builder call.

Now, add a Button builder call to the service consumer model. The button is placed on thedetails page of each contact and runs the deleteContact action list when clicked (which deletesthe currently selected contact). Fill out the Button builder call, as shown in Figure 3.13.

Notice that the Action Type input is set to ‘Link to an action’; this runs the delete operationwithout submitting the page (submitting the page is undesirable in this case, as this would try to

Page 106: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

save the current contact). Also, take note of the contents of the Page Location section of thebuilder call—the button will be placed on the contactsView_DetailsPage page (the contactsdetails page) after the update_button tag. The update_button tag is where the Edit button appearson the page, so the Delete button appears to the right of it.

Save the builder call when finished. A Delete button is now displayed on the detail page,which lets you delete the current contact and update the TESTDB database accordingly.

Creating a Contacts Portlet 69

Figure 3.13 Configuring the Delete button.

Adding Create Functionality

To add functionality from the createContact operation, first add a Comment builder call to theservice consumer model and name it Create. Save the builder call, and then add an input formfor the create function by adding an Input Form builder call to the model. Input forms are used inWPF to enable users to enter in data. Note that an input form is automatically created by WPF forthe update function in the View & Form builder call, but you need to manually create an inputform for the create function (both forms are slightly different).

Fill out the input form, as shown in Figure 3.14. This displays a form for entering in contactinformation based on the input schema defined for the createContact service operation. When theform is submitted, the createContact operation is consumed and the contactsView_ShowResultsaction list runs. Also, expand the Advanced section and uncheck the Generate Main checkbox,which prevents the builder from automatically generating a main Action List (you are alreadyusing the one created by the View & Form).

Page 107: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

70 Chapter 3 Using Data from a Relational Data Source

Figure 3.14 Configuring the Input Form builder call.

The final modification to make to the Input Form is to add a Cancel button to the form sothat users can navigate back to the view page when they’re finished. To do this, enter the textCancel into the Input Cancel Text input, and then specify contactsView_ViewPage for theInput Cancel Action input. This creates a Cancel button with the label Cancel, which returns theuser to the contactsView_ViewPage page when clicked. Save the Input Form when you arefinished.

By default, the inputs on the input form do not automatically clear when the form is loaded,so if you create two contacts, you will see that the input values are still left over from the first con-tact. This is undesirable in the present example, so you will now add an action list to clear theinput form, and then display the input form afterward. This action list is then run by a button youwill create later.

Add an Action List builder call to the model, and name it resetAndOpenCreateCon-tactPage. For the first action, select Assignment from the Special section of the Select Actiondialog. Leave the source blank (as you want to assign a null value) and enter in the input youwould like to clear into the target field (which, in this case, is the parent element of all the inputsused by the Input Form: Variables/contactsCreateContactInputs/createContactQueryInputs,shown in Figure 3.15). This sets all the inputs in the inputs variable to null values. You now needone more action in the Action List (to reshow the input form), so select createContactForm_ShowInputPage from the Select Action dialog for the second action.

You now need to add a button to the main view page so that users have a means to call upthe input page you just created. Add a Button builder call to your model, and then fill out thebuilder call, as shown in Figure 3.16. The button displays the label ‘Create contact’ and shows theinput page when clicked.

Page 108: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Contacts Portlet 71

Figure 3.15 Configuring the resetAndOpenCreateContactPage action list.

Figure 3.16 Configuring the Create button.

Notice that you need to change the Action Type input to read ‘Link to an action’ (rather thanthe default setting, ‘Submit form and invoke action’). If you don’t change this input, the submit

Page 109: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

action is called when you press the Create button (which, in this case, causes an error, as the con-tacts list page doesn’t have a form to submit). Also, notice the location of the button control—at anew HTML tag called createContact, which displays immediately before the data tag (the datatag displays the results of the view operation on the contacts service). For more information onplacing controls on forms, see Chapter 6.

Save the builder call when finished. Your service consumer model is now ready to test anddeploy to a portal server, which is covered in the next section.

Testing the Contacts Portlet

Your project now contains both a service provider model (offering create, read, update, and deletefunctions on the TESTDB data source) and a service consumer model to consume the operationson that service. In this section, you test that the service consumer can access the service providerand that it can correctly consume each operation on the service. You then rebuild the portlet appli-cation and view your service consumer model as a portlet.

Make sure the contacts model is the currently active model in your IDE. Run the contactsmodel from the WPF Designer, and the contacts list should display in your default Web browser,as shown in Figure 3.17.

72 Chapter 3 Using Data from a Relational Data Source

Figure 3.17 Testing the contacts list from the contacts model.

Click on a contact ID to open the detail page for that contact. For example, clicking HaleySmith’s ID should return the page shown in Figure 3.18.

TIP

In this example, the list and detail are surfaced in the same portlet, but sometimes theseare split into two separate portlets (one for the list and one for the detail). Clicking on a doc-ument in the list portlet opens the document in the detail portlet. This enables the list toalways be accessible (you don’t have to cycle back and forth between the list and thedetail), and the list and the detail can be shuffled around the page as the user desires. Fur-thermore, these portlets can also be used as components in other applications; forexample, clicking on a supplier in the list portlet might bring up a report for that supplier in achart contained in another portlet. Intercommunication between portlets is discussed inChapter 7, “Communicating Between Portlets.”

Page 110: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Contacts Portlet 73

Figure 3.18 Viewing a contact from the contacts model.

Click the Edit button to revise the current contact’s details. For example, clicking the Editbutton for Haley Smith should return the page shown in Figure 3.19. Change some of the con-tact’s details and press Submit, and you should see the contact record updated in the contacts list.

From the main view page, press the Create contact button. The input form should appear, asshown in Figure 3.20. Enter the details for a new contact and press Submit. You should see thecontact added to the bottom of the contacts list and be able to open the contact’s record to viewhis details.

Figure 3.19 Editing a contact from the contacts model.

Page 111: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

74 Chapter 3 Using Data from a Relational Data Source

Figure 3.20 Creating a contact from the contacts model.

Open a contact again by clicking an ID in the contacts list, and then press the Delete contactbutton. You should return to the contacts list and see that the contact was deleted.

Close the contacts model when you’ve finished testing it. You should now rebuild yourapplication on the portal server (for instructions on how to do this, see the example in Chapter 1),after which you can view the contacts model as a portlet. After you have added the portlet to apage in the portal it should appear, as shown in Figure 3.21.

Figure 3.21 The Contacts portlet.

Summary

In this chapter, you learned how to interact with a relational data source from WPF. You created asimple WPF application that contained two models: a service provider and a service consumer.The service provider contained several operations that provided create, read, update, and deletefunctionality for the TESTDB data source, and the service consumer enabled users to consumethese operations from a portlet.

The portlet developed in this chapter is just a starting point for interacting with backenddata. For more information on how to manipulate the presentation of your data (including how topaginate your data sets), see Chapters 5 and 6.

Page 112: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The next chapter, “Using Domino Data,” discusses how to interact with data from Dominodatabases, which are non-relational data sources.

Important Points

• Service consumers access data as a list and detail.

• In the context of relational data, a list is a snapshot of records from a table, which usu-ally contains only select information from each of these records. The detail offers morein-depth information on a particular record.

• The SQL Call builder is a high-level amalgamation of several other SQL builders inWPF, and it enables you to access a backend SQL data source and run SQL statementsagainst it.

• The View & Form builder is used in a service consumer to configure general options forinteracting with relational data, such as specifying the associated service operations fordisplaying the list and detail.

Important Points 75

Page 113: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 114: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

77

C H A P T E R 4

Using Domino Data

As the prevalence of portal technologies increases, being able to portalize a Lotus Notes applica-tion—that is, transition Domino data access and functionality from an existing Notes applicationinto a portal-based application—is becoming an increasingly important skill for developers tohave. This chapter describes how you can access and manipulate Domino data in a portlet. By theend of the chapter, you will know how to use the service provider/consumer pattern to interactwith a Domino database, and you will have created a sample application to demonstrate thisapproach. You will also learn how to create a stub service to test your service consumer whenyou’re not connected to a Domino server.

Both the models used in this chapter, in addition to the Notes database, are available fordownload from ibmpressbooks.com/title/9780137134465 under the Chapter 4 folder (instruc-tions for copying these files into your project are included in a readme.txt file in the same folder).You should copy the Notes database into your Domino data directory as per the instructions in thereadme.txt file; however, it is recommended that you try to create the models yourself to increaseyour understanding of the topics discussed in this chapter. Also, before you begin the examplein this chapter, you need to configure your Domino server so that WebSphere Portlet Factory(WPF) can communicate with it (this is covered in the “Configuring Lotus Domino” section inAppendix A). The following topics are covered in this chapter:

• Portalizing Notes functionality

• Configuring your environment

• Creating a service provider

• Creating a suppliers portlet

• Using a stub service

Page 115: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Portalizing Notes Functionality

Although portals should not be seen as a replacement for the Notes client, they can streamlinecommon business processes performed in Notes (such as sending emails, recording timesheets,or displaying sales reports) because the interfaces used to access a portal (usually Web browsers)are much more lightweight and accessible than a typical Notes client. Because of the comparativesimplicity of the interface, portalized Notes applications should not attempt to be monolithicapplications, but should provide a handful of important functions useful to the functioning of thebusiness. For example, an email portlet should contain an interface for sending and receivingmail, in addition to opening and adding attachments to email messages, but it does not need tocontain an interface for designing stationery (which arguably wouldn’t add enough value to theapplication to offset the added complexity). Keep in mind that portlets are only a small part of alarger context (the portal), and therefore they need to be designed in a certain way to increasetheir usability. For example, tabs in a portlet should be avoided wherever possible, because mostportals already use a tab-based navigation system, and multiple navigation points can becomeconfusing for end users.

WebSphere Portlet Factory provides several out-of-the-box tools to facilitate connectivity toDomino. This chapter aims to show how you can use these tools to quickly and easily surface apreexisting Notes application (a database of suppliers, which you can download from ibmpress-books.com/title/9780137134465) as a portlet in WebSphere Portal. Interactivity between WPF andDomino is set up through the use of a service provider model, which is then consumed from a ser-vice consumer model. The service consumer model is surfaced to a portal server as a portlet. Thischapter assumes that you are familiar with basic service terminology and the service provider/consumer pattern; if this is not the case, please refer to Chapter 2, “Providing and ConsumingServices.” Also, this chapter focuses on providing Domino functionality in a portlet, rather thanformatting Domino data. For information on some of the different ways to arrange Domino data ina portlet, see Chapter 5, “Customizing Portlet Appearance,” and for more on extending the userinterface, see Chapter 6, “Adding Basic User Interface Controls to Your Portlets.”

TIP

When building portlets based on Notes applications, it is important to remember that youshould normally port across only key functionality. Large, complex portlets can becomeunwieldy when used in the context of a portal, because portals contain other portlets andapplications (often on the same page) that can quickly add to the complexity of the interface.

Of course, there might be good reasons for why you might still port across a Notes appli-cation in its entirety. In these scenarios, it is sometimes more effective to put the originalNotes application into an iFrame portlet rather than build the portlet in WPF from scratch.iFrames provide you with a mechanism for embedding HTML documents (such as thosecreated by Web-enabled Notes databases) within the portal, and can be implemented inWebSphere Portal 6 using the Web Clipping Editor portlet. The main disadvantage of usingiFrame portlets is that they are not well integrated into the portal; the portal is only aware ofthe iFrames, rather than the applications within them, and the applications cannot easilycommunicate with other portlets.

78 Chapter 4 Using Domino Data

Page 116: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The example application discussed in this chapter contains two models: The first is a ser-vice provider, and the second is a service consumer. The first section of this chapter describeshow to set up the service provider, which provides create, read, update, and delete functionalityfor a Notes database containing supplier information. The second section covers the service con-sumer, which enables end users to interact with the service provider and is surfaced to a portalserver as a portlet. Finally, the last section of the chapter walks you through the process of creat-ing a stubbed service to test your service consumer when you’re not connected to the Dominoserver.

Configuring Your Environment

This section walks you through setting up your environment to connect to a Domino server. Notethat if you have not configured your Domino environment to connect to WPF, you should com-plete the “Configuring Lotus Domino” section of Appendix A before you proceed with thissection.

Before you can access the supplier database in Notes, you need to copy the database intothe data directory of your Domino server (the database can be downloaded from the Chapter 4folder at ibmpressbooks.com/title/9780137134465). The supplier database is a basic Notes data-base and contains the following design elements:

• A Supplier form (for adding and editing suppliers)

• A Stock Item form (for adding and editing suppliers)

• A Return form (for adding and editing information on returned stock items)

• Views for displaying documents created with these forms (Suppliers, Stock andReturns)

• Two lookup views (lookupSuppliers and lookupReturns)

• An agent called AddSupplierToMMDataSourceFromWPF (for adding the current sup-plier’s address and contact details to a text file, which can be used as a data source forrunning mail merges)

Be sure you open the database in a Notes Designer client to see how the agent, forms, andviews are constructed.

If you open the supplier database in a Notes client, you can see that the form contains a but-ton to add the current supplier to a mail merge data source (a file called supplierRecord.dat on theuser’s C drive). However, fields are the only things that come across from a Notes form into aWPF form, so the button is not accessible from WPF. If you want to display the button in WPF,you need to use a Button builder. For the code that is executed when the button is pushed, youneed to recode the procedure in a Java method (using the Java Domino API) or put the code into aNotes agent and run the agent from WPF. Chapter 16, “More Techniques for Domino,” has moreinformation on Notes agents in WPF and describes how to set up the AddSupplierToMMData-SourceFromWPF agent to run from a button on the service consumer.

Configuring Your Environment 79

Page 117: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Before you proceed, you should make sure you have a WPF project, which is used to con-tain the service provider model and service consumer model that you create in this chapter. If youhave a project from another chapter, you can use it, except you need to add the Lotus Collabora-tion feature set to the project (to do this, open the Project Properties dialog and select Lotus Col-laboration Extension from under the Integration Extensions category in the WebSphere PortletFactory Project Properties/Feature Info section). Otherwise, you should create a new WPFproject with the Lotus Collaboration Extension feature set (for more information on creatingprojects, see Chapter 1, “Introduction to WebSphere Portlet Factory”). The project will be pub-lished as a WAR file and deployed to a portal server, and you should also deploy the application toa local application server for testing. You can use the portal server if it is running on your localmachine; otherwise, it is recommended that you use the IBM WebSphere Application ServerCommunity Edition server (WAS CE) that comes with WPF.

Configuring the Domino Properties File

After you have a project with the Lotus Collaboration feature set, you need to configure yourDomino connection settings. Because you are using the Lotus Collaboration Extension featureset, a Domino connection properties file (called default_domino_server.properties) is added toyour project under the WebContent/WEB-INF/config/domino_config folder. Properties files areused to store your Domino server connection settings in WPF, and you can have multiple proper-ties files to cater for different scenarios. For example, you might have one properties file for alocal Domino server and one properties file for a remote Domino server. Each Domino builderhas an input to specify the properties file used by that builder.

TIP

If you copy a Domino properties file from one project to another, you need to open it andsave it in the new project before it can be used.

To configure the default Domino properties file, double-click the default_domino_server.properties file from the WebContent/WEB-INF/config/domino-config folder in theHelloWorld project to open it. Change the ServerName property to point to your Domino server.Note that you must specify the port you are using to connect to Domino (63148 is the defaultDIIOP port). If you are using a local Domino server with default port settings, you should be ableto accept the default server entry. You also need to change the UserName and Password propertiesto correspond to an account that has at least Editor access to any databases you want to usein WPF.

80 Chapter 4 Using Domino Data

Page 118: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

Technically, the user you specify in the configuration file needs only read access to the data-base so that you can access the database at design time. At runtime, you can use a differ-ent user to authenticate with Domino (such as the user currently accessing the application)by changing the Runtime Credentials field on the Domino Data Access builder. Specifyingan editor in the configuration file provides less security and might not be suitable in a pro-duction environment; however, it can make testing easier, particularly if you haven’t set upan alternative authentication mechanism (such as Lightweight Third-Party Authentication).

Save the properties file when you are done editing it.

Testing the Connection to Domino

Now that you’ve set up the properties file, you should test the connection to Domino from WPF.When you create your service provider model using the Domino Service Provider wizard, youknow whether the connection works because the wizard returns errors when the connection isn’tconfigured properly. However, WPF also comes with a test page you can use to test the connec-tion before you start building the service provider model, which can make your applications eas-ier to debug (because you don’t have to restart the wizard every time you want to test theconnection).

To use the test page, open the WebContent/factory/util/domino_test.jsp file in your projectusing a Web browser. The URL should be similar to the following:

http://localhost:10038/DominoExample/factory/util/testDominoConnection.jsp

substituting ‘localhost’ for the name of the application server specified in your application serverdeployment configuration. You should see a test page, as shown in Figure 4.1.

TIP

You need to have the HTTP task running on your Domino server to use this test page. If youare using only the DIIOP task, you can either temporarily start the HTTP task, or test yourconnection by creating a Domino Data Access builder in a WPF model. After you’ve addeda Domino Data Access builder, press the Get Databases and Views button—if you don’treceive any error messages, and you can see a list of databases in the Database Name list(which you can open by pressing the ellipsis button next to the Database Name builderinput), you can successfully connect to Domino.

Fill out your connection settings, and then press the Test Connection button. If you haveconfigured your settings correctly, when the page reloads, you should see a Got a connectionto the IOR message, and a list of available databases on your server should be displayed.

Configuring Your Environment 81

Page 119: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 4.1 Domino connectivity test page.

TIP

If you cannot connect to the Domino server successfully, make sure that both the DIIOPand HTTP tasks are started, your credentials are correct, and a firewall is not blockingaccess to the Domino server.

Creating a Service Provider

The service created in this section provides five operations, which let users create, read, update,and delete records in the Domino database (there are two read operations). These operations willthen be consumed by a portlet, which you create in the next section.

The service provider model created in this section use the following builders to provide itsfunctionality:

• Domino Data Access

• Service Definition

• Service Operation (x5)

These are added automatically using the WPF new model wizard.

Creating a Model

To add a service provider model to the project, select File, New, WebSphere Portlet FactoryModel from the File menu to bring up the WebSphere Portlet Factory Model dialog. On the next

82 Chapter 4 Using Domino Data

Page 120: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

screen, select your WPF project and press Next. The next screen lists different types of modelsWPF can create for you automatically. You can create service providers in WPF in two ways:using one of the options in the Select Model wizard (such as Database Service Provider) or creat-ing the service provider manually. Because you are using the Lotus Collaboration Extension fea-ture set, you also have a third option: the Domino Service Provider, which specifically caters toDomino databases. Select the Domino Service Provider option and press Next.

Defining the Service

You now need to define the service. Give the service the name suppliersService. If youcheck the Generate WSDL box, a WSDL document is automatically created for your service,enabling it as a Web service. The Generate WSDL checkbox can also be found on the ServiceDefinition builder call, so you can enable or disable your service as a Web service at any time.Web services are discussed in Chapter 9, “Using Web Services and Manipulating XML.” Leavethe box unchecked for this example.

The bottom section of the screen enables you to specify a Domino connection propertiesfile (which you configured and tested in the previous section). Accept the default setting and pressNext.

TIP

If you get errors at this stage of the wizard, it means the settings in your properties file arenot allowing you to connect to the Domino server. Make sure the username, password, andhostname in the properties file are correct, you have an active network connection betweenWPF and Domino, and you have configured your Domino environment as described inAppendix A.

On the next screen, you have to specify the database you want to connect to and the Notesview you want to use for displaying list data. Select Suppliers.nsf for the Database Name, andSuppliers for the View Name. Note that you should not have to type in either of these values man-ually; the Database Name should be available from the Choose Notes Database dialog (whichyou can open by clicking the ellipsis button next to the Database Name field), and the View Nameshould be available from the View Name drop-down list. If you cannot see the database, makesure you copied the Suppliers.nsf file to the data directory of the server you are accessing. If youcannot see the view, make sure the user specified in your properties file has at least reader accessto the database (the Suppliers.nsf database available from the download site has a default accessof Manager, so there shouldn’t be an access problem unless you change the Access Control List[ACL] or you use a different database with restricted access). Press Next when you are finished.

Specifying Operations

To specify operations for the service provider, check all the checkboxes currently on the screen;this will enable you to retrieve data from the Suppliers view and read, edit, and create documents

Creating a Service Provider 83

Page 121: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

from the Suppliers view. The delete operation is not automatically created, so you have to add itmanually when the WebSphere Portlet Factory Model wizard has finished. When you check a boxfor one of the document operations, an additional drop down will appear at the bottom of thescreen with the label ‘Form To Use For Document Schema’. Select the Supplier form from thedrop-down list. This setting specifies that the read, create, and edit document operations use theSupplier form.

The default operation names are long, so modify them as shown in Figure 4.2. Press Nextwhen you are finished specifying your service operations.

84 Chapter 4 Using Domino Data

Figure 4.2 Specifying your service operations.

Name the model suppliersService and make sure it is created in the models/chapter04directory. Press Finish to build your model.

When the wizard finishes, a new model called suppliersService is created in your projectand opens in the Model Editor and Outline view. Spend a few minutes going over the builder callsthat were automatically added to the model by WPF. The Service Definition builder call definesgeneral properties for the entire service, and the Domino Data Access builder call defines the con-nection to Domino, in addition to how the Domino data is used (such as reading and creating

Page 122: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Notes documents). This functionality is then accessed by the Service Operation builder calls inyour model, which define the public interface to the service (that is, the operations on the ser-vice). The action taken when an operation is called is specified in the Action To Call inputs on theService Operation builder calls. After the operations have been defined, service consumers cancall these operations to get access to the Domino data configured in the Domino Data Accessbuilder call (see “The Domino Data Access Builder” sidebar for more information on theDomino Data Access builder).

Adding a Delete Operation

The WebSphere Portlet Factory Model wizard did not automatically create an operation for delet-ing documents, so the next step is to make this functionality available through a service opera-tion. To do this, first add a Service Operation builder call to the suppliersService model byselecting Service Operation from the Builder Palette and then pressing OK (you can open theBuilder Palette by clicking the icon in the Outline view).

THE DOMINO DATA ACCESS BUILDER

The Domino Data Access builder specifies settings for interacting with documents andviews in a Domino database. In the top part of the builder, you need to specify a databasethat you want to connect to and the properties file that defines the link to the server wherethe database resides. The Runtime Credentials input in this part of the builder enables youto configure how user authorization is calculated when accessing the database—the defaultvalue of ‘Use regen credentials specified above’ uses the ID specified in the properties file.

The View Support section of the builder contains settings for a view in the database thatyou want to use for your list information in WPF.You can use these settings to exclude docu-ments from any data returned from Domino. For example, the Rows to Include input enablesyou to specify that only certain rows should be included (such as rows that display a cate-gory title), and the Category input specifies that only a certain category of documentsshould be displayed (based on the first categorized column in the view). There is also aSearch String input in this section, which lets you search the full text on the results returnedfrom the view. Documents that don’t fall within the search results are not returned for opera-tions that retrieve view data. Searches in this box have the following syntax:

field [fieldName] [relation] [value]

where fieldname is the name of the field to search for, value is the value of all or part ofthe field, and relation is a relation between the field and the value, either ‘=’ or ‘contains’.For example, the search string field supplierCode contains Til would returnall the documents with a supplierCode containing the text Til. The search string fieldsupplierCode=Til107 would return all of the documents with a supplierCode ofTil107. These searches can also be concatenated; for example, the search string fieldsupplierCode contains Til AND field supplierName contains Kingdom

would return all documents with a supplierCode containing the text Til and a supplierNamecontaining the text Kingdom.

Creating a Service Provider 85

Page 123: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The Document Support section of the builder specifies that you want to use a particularform to access and manipulate Notes documents from the View. The Optional Schema Set-tings section enables you to modify the schemas that WPF automatically creates for yourDomino data (which you can view under the WebApp/Schemas folder on the WebApp Treetab when editing a model). The Connection Override section lets you override the connec-tion properties set in the connection properties file specified at the top of the builder call.

The Advanced section contains several useful options for configuring the connection toDomino. For example, the Fetch Subsets of Data input can lead to faster page loading timeswhen displaying paginated data, because you can specify to only retrieve the documentsdisplayed on the current page (instead of all documents in the view). Also, the Use HTTPAccess input can be used to force WPF to communicate with Domino over HTTP (ratherthan DIIOP); however, this works only when you don’t have a search string or category spec-ified and you have the Enable View Support box checked.

The Domino Data Access builder requires additional builders (such as the View & Formbuilder call used later in this chapter) to control how the data is presented.The Domino View& Form builder, which is an amalgamation of the Domino Data Access and View & Formbuilders, is another builder that can access Domino data. The Domino View & Form builderis easier to implement than a service-based approach using the View & Form builder, and italso provides additional functionality (such as automatically building a create page for yourdata). However, the Domino View & Form builder contains inputs that affect the presentationand model tiers of your application, which ultimately makes your application more difficult tomaintain (if you are unfamiliar with these terms, please refer to the “The Model View Con-troller Pattern” sidebar in Chapter 2). As a result, the Domino Data Access builder should bepreferred wherever possible.

Adding a Domino Data Access builder call to a model will also give you access to a num-ber of methods for accessing and manipulating Domino data. For example, open up a Ser-vice Operation builder call in the suppliersService model and press the ellipsis button next tothe Action To Call input to open the Select Action dialog. Under the Methods folder, thereshould be a subfolder called suppliersServiceView containing a series of methods createdby the Domino Data Access builder call (some of the more useful methods are discussed inChapter 16). Several of these methods are also accessible from the DataServices folder inthe Select Action dialog, which you use in the example in this chapter.

The Domino Data Access builder already provides a method for deleting Notes documents,and you can run this method from the service operation. Open the Service Operation Propertiessection of the Service Operation builder and change the Data Service input to suppliersService.Change the Operation Name input to deleteSupplierDocument and the Action to Call inputto suppliersServiceView.deleteDocument. This creates an operation called deleteSuppli-erDocument that runs the deleteDocument method provided by the Domino Data Access builder(for instance, suppliersServiceView.deleteDocument).

After you have filled out the Service Operation Properties section, you should make surethe inputs and outputs for the operation are correct. Service operations use inputs and outputs todefine how service consumers communicate with them (for more information on basic serviceterminology and how services are used more generally, see Chapter 2).

86 Chapter 4 Using Domino Data

Page 124: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

In the Service Inputs section of the builder call, select ‘Use structure from called action’ forthe Input Structure Handling input and make sure Input Field Mapping is set to Automatic. Thisspecifies that the structure of the inputs to the operation is defined by the called action, which, inthis case, is the deleteDocument method provided by the Domino Data Access builder. It alsoautomatically maps inputs from the Service operation to the deleteDocument method. The delete-Document method takes one argument, which is the universal ID (UNID) of the document thatyou want to delete. The inputs for the deleteDocument method are defined in an XML schemaautomatically created by the Domino Data Access builder call.

TIP

You can have a look at the XML schemas in your model (both those that you have createdand those that WPF has created for you) by switching to the WebApp Tree tab when editinga model in the Model Editor. All the schemas used in the current WebApp are listed underWebApp/Schemas. Additionally, you can look up the inputs and outputs of a method underthe WebApp/Variables folder. Using both of these folders, you can get a better understand-ing of how the methods automatically created by WPF are defined. For example, thereadSupplierDocument method created by the Service Operation builder call will have acorresponding variable for its inputs, called readSupplierDocumentInputs. Selecting thisvariable in the WebApp/Variables folder will tell you the schema (suppliersServiceView_document) and the element (InputUNID) for this variable.You can then look up this schemaunder the WebApp/Schemas folder and browse to the InputUNID element to see whatinputs the operation is expecting.

After you have configured the Service Inputs section of the builder, you need to specify theoutputs (if any) that you want to use for the operation. In this case, no output is required, becauseyou just want to delete a particular document from the database (similarly, the updateSupplier-Document operation also requires no output, because you just want to update a document basedon the inputs passed in to the operation). Notice, however, that the other operations in the modeldo return results to the caller; for example, the readSupplierDocument operation returns all thefields on the Supplier form for the UNID specified in the inputs to the operation. The structure ofthe results returned from methods defined by the Domino Data Access builder call is defined inschemas created by the Domino Data Access builder call (which is why, in these cases, the ResultStructure Handling input is set to ‘Use structure from called action’).

To specify that no outputs are used, change the Result Structure Handling input in theOperation Results section to ‘No results’ and make sure the Result Field Mapping is set to Auto-matic. Save the builder call when you are finished.

Your service provider is now finished and ready to test.

Creating a Service Provider 87

Page 125: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the Service Provider

By default, WPF automatically generates test pages for your service provider (which you can dis-able from the Testing Support section of the Service Definition builder call). This enables you totest the service provider directly from the IDE.

To test the service, run the suppliersService model from the WPF Designer by clicking theicon on the toolbar. This runs the currently active model (for instance, suppliersService) with

the last run configuration you used. If you have not set up a run configuration before, you areprompted to do so—create a new configuration under the WebSphere Portlet Factory Model cate-gory (if you want more information on setting up a run configuration, see the “Testing the Appli-cation” section in Chapter 1).

After you run suppliersService, you should see the index test page in your default Webbrowser, as shown in Figure 4.3. This screen lists all the operations available on the suppliersSer-vice service.

88 Chapter 4 Using Domino Data

Figure 4.3 Index test page from the suppliersService model.

Testing the readSupplierView Operation

To test the readSupplierView operation, click the readSupplierView link. You should see a list ofcontacts, as shown in Figure 4.4. If not, check that you don’t have any errors showing in the Prob-lems view in the IDE and that you have completed all the steps in the previous section correctly.

Figure 4.4 Testing the readSupplierView operation.

Page 126: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the Service Provider 89

Notice that the four columns defined in the Notes view are displayed, in addition to twocolumns that WPF adds to every view by default: isDocumentRow and UNID. The isDocument-Row column denotes whether a row corresponds to a document in Notes, and the UNID columndenotes the UNIDs for each document displayed. These fields are excluded from the serviceconsumer’s output with a Data Column Modifier builder call.

Copy a UNID from one of the documents (by highlighting it and pressing Ctrl+C), becauseyou need a sample UNID for the next test. Press Back to return to the index page.

Testing the readSupplierDocument Operation

To test the readSupplierDocument operation, click the readSupplierDocument link. The screenthat follows enables you to specify parameters for the operation. Paste in the UNID you copied tothe clipboard in the previous step, and then press the Submit Query button. You should see detailsfor the supplier with the ID specified. Fred Jackson’s details, for example, are shown in Fig-ure 4.5. Note that the supplier rating is not displayed, because this field is set as ‘Computed fordisplay’ on the Notes form (so it doesn’t actually exist on the Notes document). Chapter 16 dis-cusses how to add the supplier rating to the WPF detail and update pages.

Press Back when you have finished testing the readSupplierDocument operation.

TIP

If you open the Service Definition builder call and check the Specify Default Inputs box inthe Testing Support section, you can specify default values for your testing so that you don’tneed to retype them every time. For example, if you copy a UNID and paste it into theInputUNID.UNID field for the readSupplierDocument operation, this UNID is used whentesting the operation unless another UNID is specified.

Figure 4.5 Testing the readSupplierDocument operation.

Page 127: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the updateSupplierDocument Operation

To test the updateSupplierDocument operation, click the updateSupplierDocument link. Thescreen that follows enables you to specify parameters for the operation, which are the values usedto update a particular supplier. Paste in the same UNID you copied to the clipboard earlier, inaddition to some new data for that supplier, and press the Submit Query button. If the operationworked correctly, you should be able to run the readSupplierView operation again and see that thesupplier is listed with the details you just entered. (Note: Although the test page requires you toreenter each field, these fields are automatically populated when you edit a supplier from the ser-vice consumer.)

TIP

When you save a Notes document from WPF, the inputs are validated based on the valida-tion formulas on the Notes form. In this example, the SupplierName field requires a valuewith a length of at least three characters, and the supplierCode field cannot be null. So, ifyou don’t meet these requirements, you get an error when you try to save the form.You canturn off this validation by calling the setComputeWithFormEnabled method of the DominoData Access builder and passing in the value ‘false’ as an argument.

Validation is discussed in more detail in Chapter 11, “Field Validation, Formatting, andTranslation.”

Testing the createSupplierDocument Operation

To test the createSupplierDocument operation, click the createSupplierDocument link. Thescreen that follows enables you to specify parameters for the operation, which are the values usedto create the new supplier (you don’t need to type in a UNID—this is assigned automatically).Enter in some sample data and press the Submit Query button. When the screen reloads, it dis-plays the UNID of the new document just created in Notes. Copy this UNID onto the clipboard,because you use it in the next test. Press the Back button to continue. If the supplier was addedcorrectly, you should be able to run the readSupplierView operation again and see the newsupplier.

Testing the deleteSupplierDocument Operation

To test the deleteSupplierDocument operation, click the deleteSupplierDocument link. Paste in theUNID of the supplier you created in the previous step to delete that supplier, and then press theSubmit Query button. When the screen reloads, it displays nothing but a Back button—press thisto continue. If the contact was deleted correctly, you should be able to run the readSupplierViewoperation again and see that the contact has been removed.

Close the suppplierService model when you have finished testing it.

90 Chapter 4 Using Domino Data

Page 128: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

You now have a working service provider model called suppliersService. The next sectionwalks through creating a service consumer model to consume the operations offered by this ser-vice and provides an interface to these operations in a portlet.

Creating a Suppliers Portlet

This section describes how to add a second model to your project, which offers a user interface toconsume the various supplier operations provided by your service provider. This service con-sumer model is then surfaced to a portal server as a portlet. A screenshot of the portlet is shownlater in Figure 4.18.

In this section, you use the following builders in the suppliers model:

• Portlet Adapter

• Service Consumer

• View & Form

• Comment (x3)

• Action List (x2)

• Button (x2)

• Input Form

• Data Field Modifier

Note that the model developed in this section uses only basic display options; the focus ismore on how to surface functionality to consume services that interact with a Domino database.For more information on arranging output in portlets, see Chapter 5 and Chapter 6.

Creating a Model

To create the service consumer model, select File, New, WebSphere Portlet Factory Model fromthe File menu to bring up the WebSphere Portlet Factory Model dialog. On the next screen, selectyour WPF project and press Next. The next screen lists different types of models WPF can createfor you automatically. You can create service consumers in WPF in two ways: the first is to letWPF create one for you (which you can do by using the List and Detail Service Consumer optionin the Select Model wizard), and the second is to create the service consumer manually. A list inWPF is a collection of basic data across one or more records (usually displayed in a table orchart), whereas detail is data specifically related to a single record (which usually contains datanot available in the list). The List and Detail Service Consumer gives you everything you need inthis example, so select it and press Next.

The List and Detail Service Consumer automatically surfaces your model as a portlet via aPortlet Adapter builder call. Specify the name of the portlet on the next screen as suppliers (this

Creating a Suppliers Portlet 91

Page 129: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

name is also used to name the other builder calls in your model). Also, specify the service providerchapter04/suppliersService you created in the previous section. Press Next when you are finished.

You now need to specify the service operation that is used to provide the list of suppliers.Select readSupplierView and press Next. On the next screen, fill out the boxes, as shown in Fig-ure 4.6, and then press Next. These settings are for the detail part of the data, and they convert allthe values in the Supplier_Name column in the contact list into clickable links. When a userclicks on the link, a value identifying the supplier is passed to the readSupplierDocument opera-tion, and the results are displayed to the screen.

92 Chapter 4 Using Domino Data

Figure 4.6 Specifying a detail operation.

You now need to configure the value that will uniquely identify each supplier for thereadSupplierDocument operation. Make sure the settings appear, as shown in Figure 4.7, andthen press Next. This uses the Notes UNID to identify each supplier.

Finally, give your model the name suppliers and make sure it is created in the directorymodels/chapter04. This is the name of the model as it appears in the IDE. Note: In this example,although the model name and portlet name are the same, it is possible to use different names foreach field. When you’re done, press Finish to build your model. This creates a new model calledsuppliers in your WPF project and opens the model in the Model Editor and Outline view.

Page 130: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Suppliers Portlet 93

Figure 4.7 Specifying a detail operation.

Configuring the Portlet Adapter

The suppliers model contains three builder calls: a Portlet Adapter, a Service Consumer, and aView & Form.

The Portlet Adapter builder converts the model into a portlet, which can be viewed inside aportal (note that if you make any changes to this builder call, including the changes you are aboutto make, you need to rebuild the deployed application before you can see the results of thechanges. For more information on this process, see the example in Chapter 1). The Service Con-sumer builder consumes the operation readSupplierView on the suppliersService service, and theView & Form builder displays any list and detail data in the model to the screen. The View &Form builder also enables you to do some basic manipulation of how the data is displayed (theView & Form builder is discussed in Chapter 5).

The builder calls don’t require any configuration in this example, except for two smallchanges to the Portlet Adapter builder call. Double-click the Portlet Adapter builder call to open itin the Model Editor, and then change the Portlet Title to Suppliers and the Portlet Descriptionto Interface for interacting with the Suppliers.nsf database. Save the buildercall when you are finished. The Portlet Title identifies the portlet inside the portal (it is actuallydisplayed in the title bar of the portlet), and the Portlet Description appears on various adminis-tration screens inside the portal.

At this stage, the model uses only two of the five operations provided by the serviceprovider—that is, you can read a list of suppliers from the suppliers database and view details onan individual supplier by clicking on their ID. Test the suppliers model now from your IDE (bypressing the button), which gives you some understanding of what the wizard creates by default.

Page 131: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Next, you need to add builder calls to the model to surface functionality for the create,update, and delete operations. Note that at the completion of each of the following sections, youcan test the added functionality directly from your IDE. Testing every operation on the consumertogether is discussed in the “Testing the Service Consumer” section at the end of this chapter.

Adding Update Functionality

To add functionality from the updateSupplierDocument operation, double click on the View &Form builder call in the Outline view. Scroll down to the Update Page Support section, and thencheck the Create Update Page box. Some new options appear underneath. Bring up the SelectAction dialog for the Update Method input, and then select the updateSupplierDocument opera-tion from the DataServices section (it appears in the input as DataServices/suppliers/updateSupplierDocument).

The Update Method defines what happens when new data is submitted (it runs the update-SupplierDocument operation in this case). For the Update Next Action input, select suppli-ersView_ShowResults. This input defines a post update action, and, in this case, it will refresh thesuppliers list with any changes and return the user to the suppliers list—something that is notdone automatically.

TIP

The View & Form builder creates three pages in your model:

suppliersView_ViewPagesuppliersView_DetailsPage suppliersView_UpdatePage

The name of the View & Form builder call is used as a prefix for each page. The ViewPagepage contains the supplier list. The DetailsPage is the page used to display specific infor-mation on an individual supplier, and the UpdatePage is the page used to edit a supplier.You can place controls on these pages by specifying one of them in the Page input on abuilder that creates UI elements. For more information on placing controls on forms, seeChapter 6.

Save the builder call when you are finished. An Edit button is now displayed on the detailpage, which lets you edit the current supplier and update the Suppliers.nsf database accordingly.

Adding Delete Functionality

To add functionality from the deleteSupplierDocument operation, add a Comment builder call toyour model. Name the Comment Delete and save the builder call. This Comment isn’t neces-sary, but it helps to organize your model and make clear the purpose of the builder calls that fol-low it in the Outline view.

Add another Action List to your model. This action list defines what happens when a userwants to delete a supplier. Name the Action List deleteSupplier, and then press the ellipsis

94 Chapter 4 Using Domino Data

Page 132: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

button next to the first action to open the Select Action dialog. The first action that you defineassigns the UNID of the currently selected supplier to the argument that is passed to the deleteoperation. Select Assignment from the Special heading in the Select Action dialog, and then, inthe Make Assignment dialog that follows, press the ellipsis button next to the Target box andselect arg1 from the list of the deleteSupplierDocument arguments, as shown in Figure 4.8. Thisspecifies the argument that will be set.

Creating a Suppliers Portlet 95

Figure 4.8 Selecting the target value.

Next, press the ellipsis button next to the Source box and select UNID from the currentlyselected contact, as shown in Figure 4.9. The value of this field will be used to set the value of theargument specified in the previous step. Press OK when you are finished.

For the second action in the action list, select deleteSupplierDocument from the SelectAction dialog (or type DataServices/suppliers/deleteSupplierDocument). This con-sumes the deleteSupplierDocument operation, passing in the value of the argument that was set inthe previous step. Press OK when you are finished.

For the third action in the action list, select suppliersView_ShowResults from the SelectAction dialog (or type suppliersView_ShowResults). This refreshes the suppliers list afterthe delete operation has been performed, and then returns the user to the suppliers view. Press OKwhen you are finished, and then save the builder call.

Next, add a Button builder call to your model. The button is placed on the details page ofeach contact and runs the deleteSupplier action list when clicked (which deletes the currentlyselected supplier). Fill out the Button builder call, as shown in Figure 4.10.

Notice that the Action Type input is set to ‘Link to an action’; this runs the delete operationwithout submitting the page (submitting the page is undesirable in this case, as this would try tosave the current supplier). Also, take note of the contents of the Page Location section of thebuilder call—the button is placed on the suppliersView_DetailsPage page (that is, the suppliersdetails page) after the update_button tag. The update_button tag is where the Edit button displayson the page, so the Delete button displays to the right of it.

Page 133: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

96 Chapter 4 Using Domino Data

Figure 4.9 Selecting the source value.

Figure 4.10 Configuring the delete button.

Page 134: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Save the builder call when you are finished. A Delete button is now displayed on the detailpage, which lets you delete the current supplier and update the Suppliers.nsf database accordingly.

Adding Create Functionality

To add functionality from the createSupplierDocument operation, add a Comment builder call toyour model and name the Comment Create. Save the Comment builder call. Then, add an inputform for the create function by adding an Input Form builder call. The Input Form builder is usedin WPF to enable users to enter in data (an input form is automatically created for the updatefunction, but you need to manually create an input form for the create function). Name the buildercall createSupplierForm and change the Input Submit Operation input to DataServices/suppliers/createSupplierDocument. Change the Input Next Action input tosuppliersView_ShowResults.

These changes display a form for entering in contact information based on the inputschema defined for the createSupplierDocument service operation. When the form is submitted,the createSupplierDocument operation is consumed, and then suppliersView_ShowResults runs.Uncheck the Generate Main input in the Advanced section; this prevents the Input Form fromgenerating another Action List called main (you are already using the one created by the View &Form).

The final modification to make to the Input Form is to add a Cancel button to the form sothat users can navigate back to the view page when they’ve finished. To do this, enter in the textCancel into the Input Cancel Text input, and then specify suppliersView_ViewPage for the InputCancel Action input. This creates a Cancel button with the label Cancel, which returns the user tothe suppliersView_ViewPage page when clicked. Save the Input Form when you are finished.

By default, the inputs on the input form do not automatically clear when the form is loaded,so if you create two suppliers, the input values are still left over from the first supplier. This isundesirable in this scenario, so you will now add an action list to clear the input form, and thendisplay the input form afterward. This action list is then run by a button you will create later.

Add an Action List builder call and name the action list resetAndOpenCreateSupplierPage. The first action in the Action List needs to set all the inputs to null values, andthe second action will display the input form. Open the Select Action dialog for the first actionand select Special/Assignment from the Select Action dialog. This enables you to assign a sourcevalue to a target field. Leave the source blank (because you want to assign a null value) and enterin the parent element of the inputs into the target field, as shown in Figure 4.11. Press OK toaccept the selection and then OK again to accept the action. Save the builder call.

You now need to add a button to the main view page so that users have a means to call upthe input page you just created. Add a Button builder call to your model, and then fill out the But-ton builder call, as shown in Figure 4.12. The button displays the label Create supplier and showsthe input page when clicked.

Creating a Suppliers Portlet 97

Page 135: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

98 Chapter 4 Using Domino Data

Figure 4.11 Document inputs for the create page.

Figure 4.12 Configuring the create button.

Page 136: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Notice that you need to change the Action Type input to read ‘Link to an action’ (rather thanthe default setting ‘Submit form and invoke action’). If you don’t change this input, the submitaction is called when you press the create button (which, in this case, causes an error, because thecontacts list page doesn’t have a form to submit). Also, notice the location of the button control—at a new HTML tag called createSupplier, which appears immediately before the data tag (thedata tag displays the results of the view operation on the contacts service). For more informationon placing controls on forms, see Chapter 6.

Save the builder call when you are finished.

Removing Unwanted Fields

All the functionality the service provider offers is now consumed by the service consumer; how-ever, if you tested the consumer model, you would notice that several unwanted fields (UNID andIsDocumentRow) clutter up the output. To remove these fields, you should add a Data Field Modi-fier builder call to your project (the use of this builder call is discussed in more detail in Chapter 5).

To remove the unwanted fields from your consumer model’s output, add a Commentbuilder call to your model and name the Comment Modifiers. Save the builder call when youare finished. Add a data field modifier to the suppliers model and name it hideUnwanted-Fields, and then check the Hide Element box. This removes most of the other inputs on theform and enables you to specify in the Fields input a series of fields that you want to remove.Enter in the UNID and IsDocumentRow fields for each page in your application, as shown inFigure 4.13.

Creating a Suppliers Portlet 99

Figure 4.13 Configuring the data field modifier.

Page 137: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

The Data Field Modifier should be placed after the Input Form and View & Form buildercalls, because it modifies the output they create. If you put the data field modifier first, youget a series of warnings in the Problems view stating that the field selectors for each fieldyou want to modify did not evaluate to any fields.

When you’ve finished configuring the data field modifier, save your changes. Your serviceconsumer model is now ready to test and deploy to a portal server.

Testing the Service Consumer

Your project now contains a service provider model and a service consumer model. The serviceprovider enables you to access and manipulate the Suppliers.nsf Domino database, and theservice consumer provides a user interface for interacting with the operations on that service. Inthis section, you use a local application server to test that the service consumer can access the ser-vice provider, and that it can correctly consume each operation on the service. You then rebuildthe portlet application and view your service consumer model as a portlet.

To test your service consumer using a local application server, first make sure the suppliersmodel is the currently active model in your IDE and run the suppliers model from the WPFDesigner. After you have run the suppliers model, the suppliers list should appear in your defaultWeb browser, as shown in Figure 4.14. You can change the titles of the columns and specify thenames for each column by using another Data Column Modifier builder call (this is discussed inChapter 5).

100 Chapter 4 Using Domino Data

Figure 4.14 Testing the suppliers list from the suppliers model.

Click on a supplier name to open the detail page for that supplier. For example, clickingTile Kingdom should return the page shown in Figure 4.15.

Page 138: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the Service Consumer 101

Figure 4.15 Testing the supplier detail from the suppliers model.

TIP

As with the example in Chapter 3, “Using Data from a Relational Data Source,” the list anddetail here are surfaced in the same portlet. Sometimes, the list and detail are split into twoseparate portlets (one for the list and one for the detail), an approach that is discussed inmore detail in Chapter 7, “Communicating Between Portlets.”

Click the Edit button to edit the current suppliers details. For example, clicking the Editbutton for Tile Kingdom should return the page shown in Figure 4.16. Change some of the sup-pliers details and press Submit, and you should see the supplier record updated in the supplierslist. Notice that there is no selector for the stockSupplied field, so you need to type in the stockmanually. Chapter 16 discusses how to replace the stockSupplied field with a pre-populatedselect box.

Figure 4.16 Editing a supplier.

Press the Create supplier button from the main suppliers view to open up the create supplierinput page. Enter in some new supplier details (such as those shown in Figure 4.17) and pressSubmit. Note that you don’t need to type a UNID, because this is assigned automatically. Thenew supplier should now appear in the suppliers list.

Page 139: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

102 Chapter 4 Using Domino Data

Figure 4.17 Creating a new supplier.

Open a supplier again by clicking its name in the suppliers list, and then press the Deletesupplier button. You should be returned to the suppliers list and see that the supplier was deleted.

Close the suppliers model when you’ve finished testing it. You should now rebuild yourapplication on the portal server (for instructions on how to do this, see the example in Chapter 1),after which you can view the suppliers model as a portlet. After you have added the portlet to apage in the portal, it should appear, as shown in Figure 4.18.

Figure 4.18 The Suppliers portlet.

Using a Stub Service

In the context of WPF, a stub service is a service containing preset, stubbed data that doesn’trequire connectivity to the data source. To build a stub service, you would normally create a copy ofyour service provider called a stub model. Stub models provide several benefits to the developer:

• You can work disconnected from the data source. This often provides more convenientworking conditions, and it is usually faster than working when connected to the datasource.

• You can test WPF applications (including update and create operations) without affect-ing the data source.

Page 140: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Using a Stub Service 103

• Stub models make it easier for multiple people to perform unit tests on the same datasource, because you can specify test values without affecting test values for others.

See the “Building a Stub Service” section of Chapter 2 for more general information onstub models in WPF.

In this section, you create a stub model based on the suppliersService model. You thenpoint the suppliers model to the stubbed model instead of the original suppliersService model,which enables you to test the suppliers model when you don’t have access to the Supplier.nsfdatabase.

TIP

It is recommended that you specify default values for the operations that require argu-ments, because this causes the sample data for these operations in your stub service touse real data from the data source for their results.You can set default values for operationsfrom the Service Definition builder call by checking the Specify Default Inputs box in theTesting Support section.

Creating a Stub Model

To create a stub model for the suppliersService service, open the suppliersService model in theWPF Designer, and then open the Service Definition builder call. Expand the Interface and StubModels section and type in suppliersStub in the Stub Model input. Press the Generate StubModel button to create a new stub model called suppliersStub, based on the suppliersServicemodel (this could take a minute or so, depending on the speed of your machine). You can save thebuilder call, which keeps the name of the stubbed model if you want to recreate it.

Open the suppliersStub model by double clicking on the suppliersStub model in the ProjectExplorer view. Spend a few minutes going over the builder calls in the suppliersStub model.Notice that the five service operations from the suppliersService model have been retained, andeach operation now has a corresponding Method builder call. These method calls are run from theservice operations and take the place of the Domino calls in the suppliersService model. If anoperation returns results, these results are retrieved from a Variable builder call named after theoperation. All the operations have corresponding Variable builder calls, with the exception of thedeleteSupplierDocument and updateSupplierDocument operations (because they don’t returnany values).

Notice that the Variable builder calls are all in XML and are based on schemas specified inSchema builder calls displayed at the top of the Outline view. You shouldn’t change the schemasbecause they are based on the Domino data retrieved from the Domino Data Access builder call,although the Variable builder calls can be freely modified to test different scenarios for yourapplication.

Page 141: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

104 Chapter 4 Using Domino Data

By default, the suppliersStub model doesn’t have a main action list, so it can’t be rundirectly from the IDE (although, you can link to it from your service consumer). It is sometimesuseful to run the stub model directly (such as when you are changing variable values and youwant to see whether you have entered them correctly), so if you want to do this, open the ServiceDefinition builder call in the suppliersStub model, and scroll down to the Testing Support sectionat the bottom of the builder call. Check the Add Testing Support box, which automatically checksthe Generate Main box. This generates test pages for your stub model and enables you to run themodel directly from the WPF Designer.

Click the icon on the toolbar to test the stub model using your default browser. Youshould see the same index page as the one displayed for the ordinary suppliersService servicemodel and be able to run each service operation as you did there (except you are now workingwith dummy data rather than Domino data).

Using the StubModel

There are two ways to use the stub model from your service consumer. The first is to open thesuppliers model and then open its Service Consumer builder call. Change the Provider Modelinput to chapter04/suppliersStub and save your changes. The suppliers model now uses the sup-pliersStub model as its service provider, and you don’t need to change anything else in the model.

The second method is to use a service mapping registry so that you don’t have to modifythe models themselves. To do this, create a copy of the WEB-INF/config/service_mappings/map-pings.xml.example file called suppliersMappings.xml, and paste it into the same directory. Thisfile contains settings for mapping services in your project, but is not used by default as it doesn’thave an XML extension. The file includes examples for mapping different parts of your project.

Modify the contents of the file so that it reads as follows:

<ServiceMappings>

<ForAllServices when=”run-time”>

<UseStub />

</ForAllServices>

</ServiceMappings>

Save the file when you are finished, and then close and reopen the suppliers model to makesure it is using the latest service mappings. This automatically uses the stub services in your ser-vice consumers so that you can work disconnected from the Domino server. If you want to use theordinary service again, simply comment out the ForAllServices elements in the service mappingfile (or, change the extension of the file to something other than xml).

You have now successfully created a stub model for the suppliersService model. Note thatif you intend on completing any of the extensions to the suppliersService model covered in Chap-ter 16, you should switch the Provider Model input on the Service Consumer builder call back tosuppliersService, because in Chapter 16 you will add new operations to the service (if desired,you can stub these new operations after they have been created).

Page 142: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Summary

In this chapter, you learned how to connect to a Notes database from a WPF portlet and how toprovide create, read, update, and delete functionality for Domino data. The application built inthis chapter provided this functionality via a service provider model and service consumer model.

The content of this chapter provides only a basic introduction to what you can do withDomino from WPF. Using WPF, you can also do such things as run Notes agents, evaluate for-mulas, and display categorized views from your portlets. For more information on using Dominofrom WPF, see Chapter 16. The next two chapters discuss how to work with the presentation ofyour data. Chapter 5 focuses on how to lay out data on the page—adding, removing, and movingdata, in addition to changing how it is displayed. Chapter 6 focuses on how you can add extracontrols to the page, which add functionality and improve the overall appearance and usability ofthe application.

Important Points

• You need to use the Lotus Collaboration Extension feature set to get access to theDomino builders in WPF.

• The Runtime Credentials field on the Domino Data Access builder can be used to con-trol how WPF authenticates with Domino.

• WPF projects contain artifacts for automatically testing connectivity to Domino andtesting operations on the Domino service provider.

• When you save a Notes document from WPF, the inputs are validated based on the vali-dation formulas on the Notes form. This can be turned off via the setComputeWith-FormEnabled method of the Domino Data Access builder.

• Stub models are useful for testing services because they don’t require data source con-nectivity. They can be created from the Interface and Stub Models section of the ServiceDefinition builder.

Important Points 105

Page 143: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 144: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

107

C H A P T E R 5

Customizing PortletAppearance

WebSphere Portlet Factory (WPF) provides several techniques for customizing marked-up con-tent in a portlet. This chapter focuses on the various ways in which these techniques can be used,and, by the end of the chapter, you will have a good knowledge of when and how they should beused. To demonstrate these techniques, you will also build a simple data portlet that displays a listof assets for an asset management system. The portlet enables users to drill down in the list to getmore detail on each asset. It is not possible to update asset information in the example, althoughthe techniques discussed in this chapter could be applied just as easily to update functions as todisplay functions.

The example application discussed in this chapter utilizes one model and two HTML files,which are available for download from ibmpressbooks.com/title/9780137134465, under theChapter 5 folder (instructions for copying these files into your project are included in a readme.txt file in the same folder). However, to increase your understanding of the topics discussed inthis chapter, it is recommended that you create these files yourself by following through theexample. You need to build the test portlet in the first two sections of this chapter before any of theother sections can be completed; however, the rest of the sections in this chapter can be com-pleted in any order, and you can skip sections if you are already familiar with the techniques theydiscuss.

The following topics are covered in this chapter:

• Customizing portlet appearance

• Creating a service provider

• Creating an assets portlet

• Pagination

• Data modifiers

• Working with Web pages

• Cascading style sheets

Page 145: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Customizing Portlet Appearance

In addition to traditional methods of customizing the appearance of Web content, such as writingand editing HTML pages, JSPs, and style sheets, WPF also provides a series of prepackagedbuilders that help automate the process of shifting around and manipulating marked-up portletcontent. These builders provide a robust, wizard-based interface for laying out portlet pages,while letting you leverage more traditional Web artifacts like HTML pages and JavaScript code.Web artifacts can be linked to WPF builders via inputs on the builders themselves (such as theinputs on the View & Form builder that designate HTML templates), so most WPF developersuse a combination of traditional Web artifacts and WPF builders to produce appropriate inter-faces for their applications.

Some builders deal specifically with the arrangement of data on a page, and several high-level builders encapsulate functionality from both the presentation tier (components controllingthe appearance of a portlet) and model tier (the data and business logic) of an application.Wherever possible, it is recommended that you use the builders that do not mix the presentationtier with the model tier. This enables you to use the service provider/consumer pattern in yourapplications, which loosen the coupling between your data and your front end and ultimatelymake your applications easier to maintain (for more information on the service provider/con-sumer pattern, see Chapter 2, “Providing and Consuming Services”).

The example in this chapter uses the service provider/consumer pattern to take some basicasset data for an asset information system and surface it in a portlet. The first two sections of thischapter focus on constructing the asset portlet using the View & Form builder, and the remainingsections focus on how the UI of this portlet can be extended with other WPF techniques.

The View & Form builder used in this chapter provides a useful and powerful starting pointfor the interface in the example, because the sample data is based on a list and detail that the View& Form is perfectly suited to (for more information on the list and detail components of a portlet,see Chapter 2). However, note that the View & Form is just one way of creating an interface foryour data. For example, the Data Page is another commonly used alternative to the View & Formand is particularly useful for displaying XML data (several sample applications in this book usethe Data Page; see, for example, Chapters 7, 9, 11, and 12). For more information on some of thedifferent data display techniques available in WPF, see the sidebar “Display Data in WPF” laterin this chapter. Also, the Rich Data Definition is an important and powerful builder commonlyused to control the display of your data and, in particular, to define formatting, validation, andtranslation for fields. The use of the Rich Data Definition is discussed in Chapter 11, “Field Vali-dation, Formatting, and Translation.”

Creating a Service Provider

To provide data to your assets portlet, you should create a service provider model. This modelcontains a list of asset information in an XML document and is retrieved from the test portlet youcreate in the next section. One operation is used, which retrieves the list data. The detail data isextracted from this by the assets portlet.

108 Chapter 5 Customizing Portlet Appearance

Page 146: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Before you proceed with this section, you need a WPF project to house your serviceprovider model and the assets model you will create later. If you have a project from a previouschapter, you can use that; otherwise, you should create a new WPF project. For more informationon creating projects, see Chapter 1, “Introduction to WebSphere Portlet Factory.” The project ispublished as a WAR file and deployed to a portal server, and you should also deploy the applica-tion to a local application server for testing (you can use the portal server if it is running on yourlocal machine. Otherwise, it is recommended that you use the IBM WebSphere ApplicationServer Community Edition server (WAS CE) that comes with WPF.

After you have a project set up, you need to add the service provider model. The serviceprovider uses the following builders to provide its functionality:

• Service Definition

• Schema

• Variable

• Action List

• Service Operation

They are built and discussed in this order. Note that although the order of builder calls isusually not important, occasionally, the order of your builder calls can create errors or warningsin your application. In this example, the Service Operation builder call needs to follow theSchema, Action List, and the Service Definition builder call, or you get errors claiming that thereare missing resources.

Creating a Model

Create a new model called assetsService in your project under the folder WEB-INF/models/chapter05. Because you will store your data in an XML variable rather than getting it from a data-base, you need to create the service provider manually. To do this, the model should be based onthe Empty template, which creates a model with no builder calls in it. For more information oncreating models, see the example in Chapter 1.

Defining the Service

Add a Service Definition builder call by selecting Service Definition from the Builder Palette(you can open the Builder Palette by clicking the icon in the Outline view) and pressing OK.Name the Service Definition assetsService and check the Add Testing Support box in theAdvanced section. This lets you run the model and test whether your service operation is workingcorrectly. Save the builder call when finished.

Adding an Asset Schema

The next builder call to add is a Schema, which defines the asset data returned from the service.Schemas are useful for outlining the structure of your data sets, and without one you won’t be

Creating a Service Provider 109

Page 147: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

able to use the Row Details Support section of the View & Form builder call (which displays thedetail portion of your portlet).

Add a Schema builder call and name the schema assetsSchema. Select ‘Specify explicitlyas builder input’ for the Schema Source Types input. Next, enter in the following XML into theSchema Source input. Note that this XML is also available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 5 folder:

<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

xmlns:tns=”http://wpf.ibm.com/2002/10/assetsSchema”

targetNamespace=”http://wpf.ibm.com/2002/10/assetsSchema”>

<xsd:element name=”Assets”>

<xsd:complexType>

<xsd:sequence>

<xsd:element ref=”tns:Asset” minOccurs=”1”

maxOccurs=”unbounded” />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name=”Asset”>

<xsd:complexType>

<xsd:sequence>

<xsd:element ref=”tns:Name” minOccurs=”1” maxOccurs=”1” />

<xsd:element ref=”tns:Type” minOccurs=”1” maxOccurs=”1” />

<xsd:element ref=”tns:Description” minOccurs=”1”

maxOccurs=”1” />

<xsd:element ref=”tns:Location” minOccurs=”1” maxOccurs=”1” />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name=”Name” type=”xsd:string” />

<xsd:element name=”Type” type=”xsd:string” />

<xsd:element name=”Description” type=”xsd:string” />

<xsd:element name=”Location” type=”xsd:string” />

</xsd:schema>

Save the builder call when finished.

Adding Asset Data

Create some test data based on the structure defined in the assetsSchema. To do this, add a Variablebuilder call to the model and change the name to assets. Open the Choose Variable Type dialog

110 Chapter 5 Customizing Portlet Appearance

Page 148: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

for the Type input by pressing the ellipsis button to the right of the input and select the assets ele-ment in the schema you just created (assetsSchema/assets). Press OK to accept the variable type.You should now see that the Namespace input has been filled in with the namespace from yourschema. Now, enter the following XML into the Initial Value input and save the builder call whenfinished. Note that this XML is also available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 5 folder. This XML defines four sample assets based on theassetsSchema schema, which you can use for testing the techniques discussed in this chapter.

<Assets>

<Asset>

<Name>Subcontractor Agreement</Name>

<Type>Contract</Type>

<Description>Employee contract for subcontractors.</Description>

<Location>Z:\Documents\Contracts\SubContractorAgreement.doc</Location>

</Asset>

<Asset>

<Name>WebSphere Portlet Factory 6.0.2</Name>

<Type>Software</Type>

<Description>WebSphere Portlet Factory install files.</Description>

<Location>Z:\Software\IBM\WPS6.0.1</Location>

</Asset>

<Asset>

<Name>Francis Millingtons resume</Name>

<Type>Resume</Type>

<Description> Francis Millingtons latest resume.</Description>

<Location> Z:\Documents\Resumes\FrancisMillingtonsResume.doc </Location>

</Asset>

<Asset>

<Name>Bob Hines’ resume</Name>

<Type>Resume</Type>

<Description>Bob Hines’ latest resume.</Description>

<Location>Z:\Documents\Resumes\BobHinesResume.doc</Location>

</Asset>

</Assets>

Creating a Service Provider 111

Page 149: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding an Action to Retrieve a List of Assets

Add an Action List builder call to the model and name it getAssetsList. This action listreturns the contents of the assets variable you just created and is called from the Service Opera-tion builder call you will create next. However, you need to create the action list first or you geterrors in your project indicating missing resources. Change the Return Type of the builder call toIXml. (IXml is a WPF interface used to manipulate XML and is used because there is no XMLdata type in WPF as such. For more information on the IXml interface, see Chapter 9, “UsingWeb Services and Manipulating XML.”) Then, open the Select Action dialog for the first actionin the Actions input. You can do this by pressing the ellipsis button to the right of the first row inthe Actions input. From the Select Action dialog, select Special/Return to return a value to thecaller of the Action List, and then select the assets variable (Variables/assets/Assets). Press OK toaccept the action, and then save the builder call when you’ve finished.

Specifying the getAssetsList Operation

The final builder call to add to the service provider is a Service Operation. Add the Service Oper-ation builder call now and name it getAssetsList. Point the Data Service input to the ServiceDefinition builder call created earlier (assetsService) and specify the Action To Call as getAssets-List (this is the action list you just created).

You must specify the inputs and outputs for the Service Operation. To do this, expand theOperation Inputs section and select ‘No inputs’ for the Input Structure Handling input (becauseno inputs are required; the operation just needs to return the contents of the assets Variable). Forthe Operation Results section, select ‘Specify result schema’ for the Result Structure Handling,which lets you specify the schema of your results, and then select the Assets element of theassetsSchema schema for the Result Schema input (assetsSchema/Assets). Make sure the ResultField Mapping input is set to Automatic. This specifies the structure of the results returned fromthe operation and makes sure that the results from the getAssetsList action are automaticallymapped into this schema.

TIP

The ‘Use structure from called action’ option in the Operation Inputs and Operation Resultssections take the structure of the data from whatever action you have specified in theAction To Call input.You can only use this option when the structure is either not XML or isan XML document where the schema is explicitly specified. In the example, you have speci-fied IXml as the return type for the action list, so the schema is not explicitly specified.

Your service provider is now ready to test.

112 Chapter 5 Customizing Portlet Appearance

Page 150: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the Service Provider

Because you have opted to add testing support in the Service Definition builder call, WPF willautomatically generate test pages for your service provider, which you can disable from the Test-ing Support section of the Service Definition builder call. This enables you to test the serviceprovider directly from the IDE.

To test the service, run the assetsService model from the WPF Designer by clicking the icon on the toolbar. This runs the currently active model (for instance, assetsService) with the lastrun configuration you used. If you have not set up a run configuration before, you are prompted todo so—create a new configuration under the WebSphere Portlet Factory Model category (if youwant more information on setting up a run configuration, see the “Testing the Application” sec-tion in Chapter 1).

After you run assetsService, you should see the index test page in your default Webbrowser, as shown in Figure 5.1. This screen lists all the operations available on the assetsServiceservice.

Testing the Service Provider 113

Figure 5.1 Index test page from the assetsService model.

To test the getAssetsList operation, click the getAssetsList link. You should see a list ofassets, as shown in Figure 5.2. If not, check that you don’t have any errors showing in the Prob-lems view in the IDE and that you have completed all the steps in the previous section correctly.Press Back to return to the index page.

Figure 5.2 Testing the getAssetsList operation.

Page 151: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Close the assetsService model when you’ve finished testing it. You now have a service provider called assetsService, which provides a list of asset

information.

Creating an Assets Portlet

In this section, you build an assets portlet to access the assetsService service, which you can use toexperiment with some of the different techniques available for customizing the appearance ofinformation in a portlet using WPF. The data used in the example is retrieved from an XML docu-ment retrieved from the service consumer (a screenshot of the portlet is shown later in Figure 5.6).

The model uses the following builders to provide its functionality:

• Portlet Adapter

• Service Consumer

• View & Form

Creating a Model

Create a new model called assets in your project under the folder WEB-INF/models/chapter05.To do this, the model should be based on the Empty template, which creates a model with nobuilder calls in it. For more information on creating models, see the example in Chapter 1.

Adding a Portlet Adapter

The first builder call to add is a Portlet Adapter, which surfaces your model as a portlet when theapplication is deployed to a portal server. Add a Portlet Adapter builder call now, name it assets,and then change the Portlet Title to Assets and the Portlet Description to This portlet dis-plays a list of asset information and enables you to view details on each

asset. This surfaces the assets model as a portlet called Assets. Save the builder call whenfinished.

Consuming the Service

Add a Service Consumer builder call to the model, which consumes the assetsService serviceprovider you created in the previous section. Name the Service Consumer assets and point theProvider Model input to chapter05/assetsService. Save the builder call.

Displaying Assets Data

You need a way to display the assets data in the portlet. In the present example, the View & Formbuilder is used, because it will provide functionality for drilling down on a row in the data set(that is, the detail).

Add a View & Form builder call to the model. The View & Form builder call providesoptions for displaying information in a variable based on the results of a specified Java method. Inthis case, the method is the getAssetsList operation on the assets service. Name the builder call

114 Chapter 5 Customizing Portlet Appearance

Page 152: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

assetsDataViewAndForm and bring up the Select Action dialog for the View Data Operationinput. Select getAssetsList from the DataServices/assets category and press OK. You can leavethe default values for the View Page HTML and HTML Template File inputs—these are dis-cussed later in the “Working with Web Pages” section of this chapter.

You have now defined the list portion of your data—the list of assets—but have not speci-fied how the details for each asset should be accessed. To do this, check the Create Link ToDetails box in the Row Details Support section, and then fill out the Row Details Support section,as shown in Figure 5.3. This enables you click on the Name of an asset to bring up that asset’sdetails. These details are taken from the currently selected asset in the assets XML variablereturned from the service provider. Save the builder call when finished.

Creating an Assets Portlet 115

Figure 5.3 Configuring the Row Details Support.

For more information on the View & Form builder call, see the following “About the View& Form Builder” sidebar.

ABOUT THE VIEW & FORM BUILDER

Displaying data from a backend data source in WPF is normally achieved via the View &Form builder. After you have a link to a data source through a service provider, you can thenuse the View & Form builder to provide an interface for users to interact with the data sourcevia the service.The View & Form builder is particularly useful for interacting with data in a listand detail format, and, because this builder enables you to interact with a service provider inanother model, the View & Form builder also encourages a service-oriented approach toyour applications.

The View & Form builder is split up into several sections. The first section, View PageOptions, contains inputs for configuring the list portion of your data.You designate the vari-able that contains your data in the View Variable input, and then specify a method to retrievethe list information from this variable in the View Data Operation input. The remaining inputs

Page 153: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

in this section let you paginate the results and specify HTML files that define how the resultsare displayed. The View Page HTML input defines the base page for displaying view data,which must contain a tag named data.The contents of this tag is replaced by WPF based ona design specified in the HTML template defined in the HTML Template File input. HTMLtemplates are covered in the “Working with Web Pages” section of this chapter.

The Input Page Options section enables you to create an input page for entering inparameters for the view method, which is specified in the View Page Options section. Youcan also specify various configuration options for the input page, such as defining an HTMLbase page and template and enabling schema validation.

The Row Details Support section contains inputs for configuring detail data by providinga page that displays details for a row when a link for that row is clicked. Check the CreateLink to Details box to enable this section. Note that to use this section, your variable must bedefined by a schema (otherwise, you get errors showing up in the Problems view).You don’thave to explicitly create a schema if you’re working with a variable retrieved from a WPFdata service because in these cases, WPF automatically creates the schema for you.

The Details Link Column input in the Row Details Support section specifies the columnthat users can click on to obtain detail information, and the Details Link Text input lets youoverride the values in this column with custom values. You can also specify an HTML basepage and template and control how the results are obtained (for example, from a serviceoperation or directly from the currently selected row in the data set).You can also specify textfor a Back button, which takes the user back to the list page when clicked.

The Update Page Support section lets you configure options for an update page for yourdata, which lets users edit your data. To use this functionality, a method must be available tohandle the logic that is run when the page is submitted. These methods are normally cre-ated in service providers.You can also specify post- and pre-update logic in this section anddeclare an HTML base page and template to manipulate the appearance of the form. TheEnable Update Validation checkbox lets you enable schema-based validation, and the lastthree inputs enable you to change the text of the navigation buttons used on the updateform.

The Label Translation and Sample HTML section lets you define a resource bundle forthe View & Form, which you can use to dynamically set field labels. You can also createsample HTML pages from this section, which enable you to preview what the view (or list)page and detail page will look like.These sample pages are a good place to start if you wantto modify the base HTML pages used by the View & Form builder. For example, if you gener-ate a sample View Page, WPF creates a page for you that has all the tags that the pagedepends on.You can then rearrange these tags to your liking and use the edited page in theView Page HTML input so that it is the base page for the list portion of your data.

Finally, the Advanced section lets you generate a main action list. A model with an actionlist called main is executable as a portlet or standalone Web application.The main action listcreated by the View & Form builder calls a method to retrieve the data that is displayed forthe list portion of the builder, and then displays that data to the screen. Note that the mainaction list created by the View & Form builder is not actually visible in the Outline view,although you can see it in the WebApp Tree tab of the Model Editor (under the Methodssection).

116 Chapter 5 Customizing Portlet Appearance

Page 154: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

You now have an assets model that you can use to experiment with the techniquesdescribed in the remainder of this chapter. The next section explains how to test the assets portlet.

Testing the Assets Portlet

To test the assets portlet, first run the assets model from the WPF Designer. After you have runthe assets model, you should see a list of four assets in your default Web browser, as shown inFigure 5.4.

Creating an Assets Portlet 117

Figure 5.4 Testing the assets model.

Click on the name of an asset to test whether the detail component of the View & Formbuilder is working. For example, if you click on Bob Hines’ resume, you should see the output inFigure 5.5. The detail portion of your data normally contains more fields than that displayed inthe list portion; however, in this case, the same amount of fields are displayed in both. The “DataModifiers” section of this chapter discusses how you can remove fields from the list and detailportions of your portlet.

Figure 5.5 Displaying detail information for Bob Hines’ resume.

Note that you can and should test your application regularly as you progress through thischapter, especially at the end of each section. Aside from enabling you to see the output yourbuilders produce, this also makes it easier to troubleshoot any errors that arise. Be aware, how-ever, that if you test in the middle of a section, you may get errors related to missing componentsthat haven’t been built yet. The text prompts you to test your application at opportune testingpoints.

After you have tested the assets model, you should rebuild your application on the portalserver (for instructions on how to do this, see the example in Chapter 1). Then, you can view the

Page 155: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

assets model as a portlet on the portal server. After you have added the Assets portlet to a page inthe portal, it should appear similar to Figure 5.6.

118 Chapter 5 Customizing Portlet Appearance

Figure 5.6 The Assets portlet.

DISPLAYING DATA IN WPF

When dealing with list and detail data, the View & Form builder is an ideal way to display thedata because it comes with numerous options specifically catering to a list and detail. TheView & Form builder can also be used as part of a service-based design (that is, when yourdata is available via a service provider and accessed from a service consumer) because itdoesn’t mix the presentation of your application with your data. The View & Form buildersimply links to data available in the model; it doesn’t define where this data comes from orhow it should be retrieved.The View & Form builder is discussed in detail in the later sectiontitled “View & Form.”

However, several alternatives are available that might be more suitable in certain circum-stances.This section describes some of the more commonly used alternatives for displayingdata in WPF.

The Data Page Builder—The Data Page builder is the primary alternative to the View &Form and maps data from a variable or XML schema onto an HTML page.The interfaces forboth builders are similar, and if you understand one, you can understand the other.The DataPage does not provide functions for a list and detail per se, but it does enable you to imple-ment both read and edit functions for a dataset.You would use a Data Page builder insteadof a View & Form for the Data Page-specific functionality that the View & Form doesn’texpose, such as more control over field validation, or if your data was not in the form of a listand detail. As a result, data pages are particularly useful for displaying input pages or resultspages. For example, you might define the fields for a form in an XML schema, and then dis-play these inputs on an HTML page using a Data Page builder.

The Data View Builder—The Data View builder is an older builder included for backwardcompatibility. It is not recommended that you use this builder, because it mixes the presenta-tion tier of your application with the model tier (that is, the data access and the user interfaceare all controlled in the same builder).

Page 156: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The Domino View & Form Builder—The Domino View & Form builder combines thefunctionality of the View & Form builder and a builder used to interface with Domino datacalled the Domino Data Access builder. The Domino View & Form builder makes it easier tocreate an interface for accessing and manipulating Domino data and provides additionalfunctionality (such as automatically building a create page for your data). However, theDomino View & Form builder also tightly couples the presentation of your portlet to the datait displays because they’re both defined in the same builder, so you can’t provide the datavia a service. Ideally, you should be able to change the data tier in your application withoutnecessarily affecting the presentation tier, because this makes your applications easier tomaintain. Therefore, it is recommended that you use only the Domino View & Form builderfor testing purposes and not deploy models containing this builder into production environ-ments. In production environments that communicate with Domino, a service-basedapproach using a combination of the View & Form builder and Domino Data Access buildershould be preferred. An example using this approach is given in Chapter 4, “Using DominoData.”

The remainder of this chapter discusses the various options available in WPF for arranginginformation in a portlet.

Pagination

The process of viewing large numbers of records and documents in a portlet is made easier withthe use of automated pagination features in WPF. Using WPF, you can automatically convert longlists of data into separate pages, which can then be cycled through using buttons at the bottom ofeach page. Each page is viewed by reloading the list page of your data set, except only a certainpart of the data is displayed.

In WPF, pagination is implemented using a paging assistant. A paging assistant providesseveral useful methods for paginating data, such as returning page counts, and can be linked tofrom other WPF builders to do such things as placing navigation controls on the screen. A pagingassistant can be explicitly added (using the Paging Assistant builder) or added automaticallyusing one of the builders with support for pagination, such as the View & Form builder. If you areusing the View & Form builder (as in the present example), the easiest way to implement pagina-tion is to check the Paged Data Display box of the View & Form builder. This reveals anotherinput called Rows per page, which you can use to configure the size of each page, and it also auto-matically gives you access to a paging assistant in your model. You can cycle through each pageusing several buttons automatically created by WPF. Figure 5.7 shows an example of what thedefault pagination controls look like using the View & Form builder call in the assets application.

Although the View & Form builder already provides some pagination capabilities, you cancustomize these by using other WPF builders. The next example shows you how you can do thisin the assets application.

Pagination 119

Page 157: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

120 Chapter 5 Customizing Portlet Appearance

Figure 5.7 Testing the pagination capabilities of the View & Form builder.

The following builders are added in this section:

• Visibility Setter

• Paging Buttons

Turning on Pagination

Turn on pagination in the View & Form builder call as just described and set the page length to 3,which causes your data to appear in pages of three records (you don’t have many records in yourdata set, so if you set it to more than three, you won’t be able to see the pagination in use). Savethe builder call when finished.

Modifying the Paging Buttons

If you preview your application now, you should see the output shown in Figure 5.7. Using theView & Form, you don’t have much control over the navigation controls, so to modify these con-trols, you should replace the default buttons using a Paging Buttons builder call. A Paging Linksbuilder is also available, but buttons are used in this example. Before you do this, however, youcan hide the navigation controls created by the View & Form by using a Visibility Setter. Visibil-ity Setters can be pointed to a particular tag on an HTML page and hide the contents of that tagbased on a condition you specify. Add a Visibility Setter builder to your model and call it hide-View&FormNavigation. Point the Page input to the view page (hideView&FormNavigation) andthe Tag input to the navigation controls used by the View & Form (paging_buttons). Note that youcan find out the names for tags used by WPF builders if you switch to the WebApp Tree tab in theModel Editor and navigate through the Page section.

In this example, you want the navigation buttons to be always hidden, so make sure the Vis-ibility Rule input is set to Always Hide. Save the builder call when finished.

You no longer have any navigation controls in your portlet, so add a Paging Buttons builderto your model to regenerate these buttons. Fill out the inputs, as shown later in Figure 5.8. Noticethe pagingAssistant created by the View & Form is referenced in the Assistant Name input, whichspecifies the pagination assistant used by the buttons. Also, note that the buttons are inserted afterthe data tag, which is used by the View & Form to place the view results onto the page.

Save the builder call when finished.

Page 158: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 5.8 Configuring the Paging Buttons builder call.

WARNING

The Paging Assistant shouldn’t be used in conjunction with the Category View builder. TheCategory View builder is intended as an alternative to pagination, and if you are using theCategory View, you need to change the structure of your view so that its contents can fitwithin a single portlet page.

By default, the Check For New Data and Preserve Location checkboxes are marked.Thiswill mean that every time data is fetched from the source variable, a check is performed tosee if it has changed. If it has, the displayed data is updated. Also, whenever data isupdated, the current page location is retained, rather than being reset to zero.

The Paging Buttons builder contains several sections that let you customize the appearanceof the buttons as they appear on the page. Modify the Range Text Format input so that it readsPage {page} of {page_count}, and then insert the text ‘Go to’ (with a trailing space) intothe Alt Text input under the First Button Images, Prev Button Images, Next Button Images, andLast Button Images sections. Save the builder call when finished.

You have successfully configured pagination in the assets application. Now, if you test theassets application, you should see the pagination controls shown in Figure 5.9. Notice that if youhover the mouse over each navigation button, ‘Go to’ appears at the start of each help text pop-upmessage.

Pagination 121

Page 159: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

122 Chapter 5 Customizing Portlet Appearance

TIP

When you paginate data from a backend data source, you don’t necessarily want to refreshthe data set from the backend every time you change pages, because it slows down theportlet. To stop the portlet from checking the backend for changes on each page refresh,uncheck the Check for New Data box on the Paging Assistant builder (although note thatwith this setting disabled, the display is refreshed only when the portlet is loaded).

If you’re using a Service Operation builder call, you can also restrict the data (records ordocuments) retrieved in each fetch so that only the data required for the current page isretrieved. To do this, select Page Enable for the Page Enable Options input in the PagingOptions section of the Service Operation builder. Note that if you’re using Domino data, youcan also fetch paginated data by checking the Fetch Subsets of Data box in the Advancedsection of the Domino Data Access builder.

Figure 5.9 The assets model with added pagination controls.

Data Modifiers

To modify how data appears on a page, WPF provides numerous builders, commonly referred toas data modifiers. These modifiers are discussed next. An example at the end of this sectiondemonstrates how you can use these modifiers in the assets application.

The Data ColumnModifier Builder

The Data Column Modifier builder is arguably the most useful builder for manipulating theappearance of columns in a table. Using the Data Column Modifier, you can reorganize columns;hide columns; add new columns, including a counter column, which shows the number of eachrow in the data set; change column widths and headings; and specify sortable columns. You canalso specify an HTML template for the table itself, and you can even paginate the data in thetable, although the pagination options available are more limited than those offered by the PagingAssistant, Paging Buttons, and Paging Links builders.

Page 160: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Data Modifiers 123

TIP

Using WPF, you can configure pagination in numerous places. However, all these placesuse the same pagination mechanism, so it doesn’t matter which one you decide to use.However, as a general rule, you should specify paging in one place, and ideally specify onlyone layer of navigation controls, as pagination settings defined in more than one place canlead to problems. Also, although it is technically possible to use multiple layers of navigationcontrols (such as when you use the Paging Buttons and Paging Links builders together), itcan be difficult to maintain and use.

Figure 5.10 shows some sample settings for the assets view columns in the assets portlet.

Figure 5.10 Example view column settings.

The Add Counter Column checkbox adds a column to the page displaying a counter, andthe Add Columns input lets you add extra columns not included in the data set referenced by thebuilder. The Manage Columns input provides settings for each column as seen in the table at thebottom of Figure 5.10. These columns are explained briefly:

Column Name—The name of the column as it occurs in the data set.

Status—Whether the column is displayed or hidden.

Column Heading—The heading label for the column.

Column Width—The width of the column in pixels.

Alignment—How the column data is aligned (left, right, center, or default, whichmakes no adjustment to how column data is displayed).

Column Sort Type—Whether the column is sortable.

In addition to these configuration options, the Data Column Modifier also contains a ‘Set-tings for Add and Delete Row Operations’ section. This section lets you generate a delete button

Page 161: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

124 Chapter 5 Customizing Portlet Appearance

for each column and create methods for adding and deleting rows. Note that these methods onlyadd and remove entries from the variable displayed. If you want to update a data source, youeither need to use existing methods from other builders or write your own.

The example at the end of this section describes how you can use the Data Column Modi-fier to manipulate the appearance of the assets view in the assets portlet.

The Data HierarchyModifier Builder

The Data Hierarchy Modifier builder is used to group data on a page. In the example at the end ofthis section, you see how you can sort the fields on the assets detail page into two separate sec-tions: Basics and Details. As with the Data Column Modifier, you can also reorganize, rename,and hide elements on a page.

The Data Field Modifier Builder

The Data Field Modifier enables you to manipulate the appearance and behavior of individualfields on a form, and it gives you much more control over field properties than what you havewith the Data Column Modifier and Data Hierarchy Modifier. Although, with the exception ofbeing able to specify HTML templates, you can’t modify the layout of fields using the Data FieldModifier. The Data Field Modifier builder is split up into several sections, which are discussedbelow.

Aside from the Properties section common to all WPF builders, which lets you enable ordisable the builder, enter comments, and specify a sorting category, the top part of the Data FieldModifier (shown in Figure 5.11) enables you to specify one or more target fields for the builder towhich all the inputs in the builder apply. You can then generate labels for these fields and flagthem as hidden or repeating fields if desired (if you leave these inputs set to ‘Do not change,’ theunderlying settings of the field is used).

Figure 5.11 Data Field Modifier builder settings.

Page 162: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The next section of the builder is either Field Settings or Container Settings, depending onthe type of target fields specified. The Field Settings section lets you specify a lookup table for thetarget fields and designate whether the target fields are data entry fields, view only fields, oraction fields. Action fields are fields that can perform an action when you click on them, such asopening a page or running a script. The type of field determines the remaining options in this sec-tion—for example, Figure 5.12 shows the Field Settings section for a mandatory, user-editabletext input box. You can also use the Field Settings section to specify whether the user is requiredto enter a value for the field when it is part of an input form and set a default value for the fieldwhen the model is first loaded for each user.

Data Modifiers 125

Figure 5.12 The Field Settings section of the Data Field Modifier.

The Container Settings section (shown in Figure 5.13) lets you add HTML controls andlabels for the contents of the container, in addition to control the direction that the contents dis-play in. You can also use the Container Settings section to enable paging for the contents. Notethat this section displays only if the fields specified in the List of Fields input are containers (thatis, they contain child fields).

Figure 5.13 The Container Settings section of the Data Field Modifier.

The Formatting section displays only if you have individual fields specified as target fields,and it lets you specify their validation, translation, and formatting settings. Figure 5.14 shows anexample specifying that target fields are formatted as dates. Manipulating field formatting, vali-dation, and translation formulas is covered in Chapter 11.

Page 163: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

126 Chapter 5 Customizing Portlet Appearance

Figure 5.15 The Attribute Settings for the Fields section of the Data Field Modifier.

The HTML Class Settings section lets you specify an HTML template for the fields, asshown in Figure 5.16. HTML templates are discussed in the “Working with Web Pages” sectionof this chapter.

Figure 5.14 The Formatting section of the Data Field Modifier.

The next section is the Attribute Settings for Fields section, shown in Figure 5.15. As withthe Formatting section, this section shows only if you have individual fields specified as targetfields. You can use this section to specify HTML attributes for the target fields, such as class andwidth.

Figure 5.16 The HTML Class Settings section of the Data Field Modifier.

Page 164: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Data Modifiers 127

The Form Layout Builder

The Form Layout builder enables you to create newspaper-style columns for your detail pages.This gives you added flexibility in how you organize your data, but should be used with caution—keep in mind that portlet interfaces are normally small, and if users have to scroll in a Webbrowser, they are more accustomed to scrolling vertically than horizontally.

The following example shows how you can use all four of the builders in the assets applica-tion. The following builders are added in this section:

• Comment

• Data Column Modifier

• Data Hierarchy Modifier

• Data Field Modifier

• Form Layout

Adding a Data ColumnModifier

Add a Comment builder call to the model and name it Data Modifiers. This Comment willmake it easier to organize the builders in your model. Save the Comment builder call when fin-ished. Now, add a Data Column Modifier builder call to the assets model. In this example, youuse the Data Column Modifier to modify the appearance and functionality of the view page.

Press the ellipsis button next to the Container Field input, which opens the Data Field PageChooser dialog. Select the asset row from the view page, as shown in Figure 5.17. Some extrainputs now appear on the Data Column Modifier builder, which you can use to customize eachasset row.

Figure 5.17 Selecting the Container Field.

Scroll down to the bottom of the ‘Settings for Add and Delete Row Operations’ section,where the columns on the view page are listed. Change the Status column for the Description and

Page 165: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Location fields to ‘Hide’, which hide these columns from the view page. Users can still see thisinformation when they open an asset’s detail page. Change the Column Width columns for Nameand Type to 200 and 60 respectively, which set the width of these columns to a fixed number ofpixels. (Note: The numbers in this column do not represent the numbers of characters in a field,so they are constant no matter what fonts and font sizes are used.) Setting column widths keepsthe table width constant when switching between pages. If you don’t specify these settings, col-umn widths automatically adjust depending on the length of the values in the columns.

Now, change the Column Sort Type column for the Name and Type columns to ‘CaseInsensitive String’. This converts the column headings into hyperlinks. Users can now sort theinformation in the view in ascending/descending alphabetical order by alternatively clicking theheader links.

The columns in your Data Column Modifier should now appear, as shown in Figure 5.18.Save the builder call when finished.

128 Chapter 5 Customizing Portlet Appearance

Figure 5.18 Configuring the Data Column Modifier builder call.

Adding a Data HierarchyModifier

Add a Data Hierarchy Modifier builder call to your model. In this example, you use the DataHierarchy Modifier to split up the assets detail form into two sections: Basics and Details. Pressthe ellipsis button next to the first row in the Fields input, which opens the Data Page Field Inputdialog. Select the Asset for the details page, as shown in Figure 5.19, and then press OK. The boxat the bottom of the Data Hierarchy Modifier is now populated with the fields on the asset detailform.

Type in Basics,Details in the New Group Names input, and then press the Enter key onyour keyboard. This creates two new sections in the field list at the bottom of the screen, whichyou can use to organize your data. Each group has a start and end tag, and everything within thesetags is contained within that specific group. Drag and drop the start and end tags so that theyappear, as shown in Figure 5.20, and then save the builder call.

Page 166: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Data Modifiers 129

Figure 5.19 Selecting the Asset for the details page.

Figure 5.20 Configuring groups for the details page.

Adding a Data Field Modifier

Add a Data Field Modifier builder call to the assets model. In this example, you use the DataField Modifier to set the class HTML attribute of the Name field on the details page so that itappears in a larger font.

Press the ellipsis button next to the first row in the Fields input, which opens the Data PageField dialog. Select the Name field on the details page, as shown in Figure 5.21, and then pressOK. Some new inputs are added to the Data Field Modifier, which enables you to manipulate var-ious aspects of the Name field on the detail form.

Page 167: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

130 Chapter 5 Customizing Portlet Appearance

Figure 5.21 Selecting the Name field on the details page.

Scroll down to the Attribute Settings for Fields section and add an attribute called classwith the value OutputDataCell. Because the Name element already has a class attribute specified,make sure you also set the Overwrite Rule input to Overwrite HTML value, or the existing classattribute is retained. The new value for the class attribute, OutputDataCell, refers to a class speci-fied in the gridtable.css style sheet, which is located in the WebContent/factory/html_templatesdirectory in your project. This new class increases the font size of the field. Style sheets are dis-cussed in the “Cascading Style Sheets” section at the end of this chapter.

Save the builder call when finished.

Testing the Data Modifiers

Because the Form Layout builder alters the appearance of the groups created by the Data Hierar-chy builder, you should test your application now before you add the Form Layout builder call.When you run the assets application, you should see the page shown in Figure 5.22. Notice thatyou can click on a column heading to sort the information in the table on that column. If youcycle between pages, the width of the table stays constant.

Figure 5.22 Page layout after the Data Column Modifier.

If you click on an asset to open the details page, you see that the page has been split intotwo separate sections called Basics and Details, and that the Name field stands out from the otherfields on the page because it is printed in a larger font. For example, if you click on the link forFrancis Millington’s resume, you should see the details page shown in Figure 5.23.

Page 168: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Data Modifiers 131

Figure 5.23 The details page for Francis Millington’s resume.

If you view the page source for the details page (you can do this in Internet Explorer byselecting Source from the View menu) and scroll down to where the Name field appears, you seethat the Name field has a class attribute of OutputDataCell as follows:

<SPAN name=”Name” class=”OutputDataCell”>Francis Millington’s

resume</SPAN></TD>

Adding a Form Layout

The last data modifier to add is the Form Layout builder. Add a Form Layout builder call to yourmodel and name it assetsFormLayout. In this example, you use the Form Layout builder tomodify the data on the assets detail page so that it appears in two columns instead of one. In theFields input, specify the Asset node on the detail page, as shown in Figure 5.24. Change the Num-ber of Columns input to 2 and save the builder call.

Figure 5.24 Configuring the Form Layout builder.

Open the Data Field Modifier builder call by double-clicking on it in the Outline view.Notice that the majority of the inputs on the builder call have been hidden—this is because theName field as specified in the Fields input has been renamed by the Form Layout builder, so theData Field Modifier no longer recognizes the old reference. Press the ellipsis button next to thename field specified in the Fields input and select the new name field, as shown in Figure 5.25.Save the builder call when finished.

Page 169: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 5.25 Changing the Name field.

You will notice some warnings in the Problems view, which are caused by the Data FieldModifier not being able to access the results of the Form Layout builder because the Form Layoutcomes after the Data Field Modifier in the Outline view. To remove these warnings, click anddrag the Form Layout builder in the Outline view so that it comes before the Data Field Modifier.Save your model when finished.

If you test the assets application now and open an asset’s detail page, you see that the data islisted in two separate columns. For example, if you open the detail for WebSphere Portlet Factory6.0.2, you should see the output shown in Figure 5.26.

132 Chapter 5 Customizing Portlet Appearance

Figure 5.26 The details page for WebSphere Portlet Factory 6.0.2.

Working with Web Pages

Web pages form the basis of every WPF portlet. When you generate your application, WPF takesthe Web pages it contains and builds them into a JSP, which is then accessible as a portlet. Muchof the Web page creation process is automated in WPF; however, working directly with a markuplanguage (such as HTML) can give you more control over the appearance of your applications,even if it is just to make small additions to the pregenerated code.

Page 170: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

When using Web pages in WPF portlets, it is important to remember that they are accessedwithin the context of a portal (for instance, as a table cell within an HTML table). So, althoughyour models can be run as standalone Web applications, they also need to be formatted so thatthey will display correctly when placed into table cells on a portal page. You can still use<HTML>, <HEAD>, and <BODY> tags in WPF, because WPF generates the content for thesetags appropriately when outputting content to a portlet, but just make sure you don’t push otherportlets off the page by making your pages too large. Also, don’t rely on users being able to cycleback and forward between your pages unless you include some sort of navigation controls,because portals are unsuited to navigation that isn’t a part of the portal or portlets themselves. Ifyou do implement your own navigation, keep it simple, because the portal will likely have its ownnavigation, and you don’t want to clutter the interface. Also, make sure that all of your navigationoccurs within the portlet itself; don’t create pop-up pages that open outside of the context of theportal. This sort of page will not be subject to the navigation system used in the portal, whichcould cause confusion for end users.

You can view what your model’s generated pages will look like by navigating to the Pagessection of the WebApp Tree tab. Although you can’t change these pages from the WebApp Treetab, there are several other ways to change the pages in your application, which are discussed next.

HTML Builders

Pages stored in HTML files (files with a .html extension) can be referenced from a WPF applica-tion by using the Imported Page builder, provided that the HTML file exists within the file struc-ture of the application. Alternatively, you can also use the Page builder to type in an HTML pagedirectly into a builder, which is useful for small HTML fragments that don’t need to be sharedacross projects. If there is a possibility that you will reuse the HTML, you should use HTML filesinstead, because they are easier to share between projects. After you have an HTML page in WPF,you can then display the page by typing in the name of the Imported Page or Page builder into anaction list or Java method.

For example, in an empty WPF model, you could add a Page builder call named page1, andthen add an Action List builder call named main. The main action list would run every time theapplication starts. You could then type in page1 in the main action list, which would display thepage when the main action list runs. After this has been done, you could insert elements fromother HTML pages or builders onto the page created by the Page builder, giving you completecontrol over what is displayed and how it is displayed.

TIP

Many of the builders in WPF (such as the View & Form and Data Page) use HTML files asbase pages to display their output. WPF requires that certain tags exist on these pageswhen it places controls onto the form, so if you want to modify them, it is best to use theexisting base HTML pages as a starting point. Many of the HTML-generating builders comewith a Create Sample HTML button for this purpose.

Working with Web Pages 133

Page 171: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

134 Chapter 5 Customizing Portlet Appearance

You can insert HTML content onto a page through the use of named tags (<span> and<input> tags are the most commonly used). Builders that produce HTML output can be used toreplace the contents of these tags, or place controls in a certain position relative to the tags(before, after, wrapped to the left of an enclosing table, and so on).

For example, let’s say you type in the following span tag into an HTML page:

<span name = dataPage></span>

You then create a Data Page builder call in your model. Now, you can set the Location forNew Tags input to dataPage and the Location Technique to On Named Tag, which replaces thedataPage span tag with the contents of the data page. Every builder in WPF that creates HTMLhas similar inputs, which enables you to insert the results of that builder onto a page. Because youcan also replace input tags, you can replace any inputs on an HTML page with custom WPFinputs.

TIP

Note the closing tag in the example. All elements that need to be closed should be explicitlyclosed off in a separate tag. For example, the tag <span name = dataPage /> is notconsidered closed.

In addition to the WPF builders that produce generated HTML output, there is also anHTML builder that you can use to insert an explicitly specified HTML fragment (specified insidethe builder) at a particular span or input tag. Alternatively, you can also use the Inserted Pagebuilder, which inserts an entire HTML page (which you might have specified using a Page orImported Page builder) inside another page.

TIP

Although it is also possible to use the Model Container builder to insert the output of anentire model onto an HTML page, you should only use this process if you explicitly needfunctionality provided by the model specified in the Model Container. If you just want to dis-play an HTML page, you should use one of the other HTML builders instead.

When specifying HTML events in WPF, you can either code them directly into an HTMLpage or you can use the HTML Event Action builder. Using the HTML Event Action builderoffers some advantages over coding events directly into HTML pages because it makes it easierto interact with other WPF methods and builders, and several configuration options are given tohelp streamline the process.

Page 172: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

JSP Builders

As with HTML pages, JSPs can be imported into an application with the Imported Page builderand inserted into other pages via the Inserted Page builder (although, you cannot use the Pagebuilder for JSPs). JSPs can also be imported using the JSP Proxy Page builder. A restriction ofusing JSPs in WPF is that you can’t set response headers or use forwarding, because JSPs areinvoked using the include command, which doesn’t allow these actions. If you want to redirectusers to a certain page, you should use the Java processPage method of the WebAppAccessobject, as shown here (using Java in WPF is covered in Chapter 8, “Using Java in Portlets”):

webAppAccess.processPage(page2);

Three JSP-specific builders are used in WPF. The first of these is the JSP Directive builder,which lets you insert JSP directives onto a page. JSP directives let you do such things as accessclasses and tag libraries on a page. The JSP Proxy Page builder, aside from letting you importJSPs into your project, lets you intercept calls to these JSPs with methods or action lists specifiedin WPF. This is useful to replace the functionality of JSPs without breaking any links in yourapplication. For example, instead of displaying a JSP error page, you might choose to run a log-ging script in WPF, and then display an alternative HTML page. Using the JSP Proxy Pagebuilder, you can do this without modifying any of the references to the original JSP. Finally, theJSP Tag builder provides an easy interface for inserting JSP tags onto a page. The builder lets youspecify a tag library, and then provides inputs for the attributes associated with the tag that youspecify.

JavaScript

As in ordinary HTML development, a JavaScript script can be explicitly included inside anHTML page, which gives you access to that script elsewhere on the page. Some of the defaultHTML templates (such as gridtable.html) include embedded JavaScript scripts, and severalJavaScript script files are created by default in every WPF application (stored under the WebCon-tent/factory/clientjavascript directory). These script files let you do such things as display calen-dar and people pickers on a form and provide functionality for some of the Ajax builders (Ajax isdiscussed in Chapter 13, “Using Ajax and Dojo”).

If you want to write your own scripts, you should store them in a different directory to thedefault JavaScript directory so that you do not mix up the default scripts with your own (forexample, you might use WebContent/chapter05/clientjavascript). These scripts can then beaccessed from other HTML pages or builders. You can also specify JavaScript in-line, insidebuilders that let you execute actions, such as the Button builder and Action List builder. There isalso a Client JavaScript builder, which lets you insert client-side JavaScript at a specified tag on apage. However, wherever possible, you should store your scripts in the project’s file structurerather than specifying them in-line, because this makes it easier to share the scripts betweenprojects.

Working with Web Pages 135

Page 173: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

When using JavaScript in WPF, you can access WPF artifacts from within your scripts.This lets you do things such as retrieve values from WPF variables and execute WPF actions andJava methods. You can do this using the following syntax:

${WPFArtifactType/WPFArtifactName}

WPFArtifactType is a design artifact in the WebApp (such as a Method or Variable) andWPFArtifactName is the name of the artifact. You can find out the types and names of artifacts bybrowsing the WebApp Tree tab or looking at the entries in a Select Action dialog. The text of theWPF call in the JavaScript is substituted with any results returned by running the artifact in WPF.For example, to run a method called getAssetID that returns a String value, you might use the fol-lowing script:

var assetID = ‘${MethodCall/getAssetID}’;

Notice that the method call is enclosed in single quotes. The reason for this is that the resultof calling getAssetID is substituted for the method call, so without the quotes, the line might readsomething like this when loaded in a browser:

Var assetID = AB1234;

This will cause a syntax error, because AB1234 is a String literal and not a variable name.Be aware, also, that these actions are evaluated when the scripts load, so if you’re running WPFactions that display pages, the pages are inserted into your HTML as the JavaScript is loaded.

New to WPF 6.0.1 is support for the JavaScript Dojo toolkit, and WPF comes with severalbuilders to make it easier to integrate Dojo into your applications. The Dojo toolkit gives youaccess to numerous powerful interface improvements, such as a rich text editor and dragging anddropping capabilities. The DOJO builders are covered in more detail in Chapter 13.

As in ordinary Java portlet development, JavaScript should be used with caution in WPFdevelopment. Different browsers often have different JavaScript implementations, so minimizingthe amount of JavaScript in your applications can help to mitigate potential usability problems.Also, the more JavaScript in your application, the harder it is to extend your applications to othermarkups besides HTML. This might not be much of an issue for you, but JavaScript can defi-nitely help to improve users’ experience of your application. Just make sure to take the appropri-ate precautions; for example, if your application is going to be accessed through differentbrowsers, it might help to check for different browser versions when using JavaScript. Also, insome circumstances, it might be useful to test whether JavaScript is enabled when the page loads,and then provide a non-JavaScript version of the page when necessary.

HTMLTemplates

HTML templates contain standard page structures and formatting for an application, and are usedextensively in WPF to modify the output for some of the page automation builders (the buildersthat produce HTML for you). HTML templates are used by these builders to determine how youruser interface should be generated. You don’t necessarily have to change these templates, and

136 Chapter 5 Customizing Portlet Appearance

Page 174: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

doing so can be complicated; so it is recommended that you use style sheets and the WPF datamodifier builders, such as the Data Field Modifier, as an alternative to modifying HTML tem-plates wherever possible. However, HTML templates can provide you with that extra degree ofcontrol in your user interface, and they can also be shared easily between applications.

TIP

HTML templates in WPF can be profiled so that different templates are used depending onthe context in which your portlet is used. For more information on profiling in WPF, seeChapter 12, “Profiling Portlets.”

You can think of an HTML template as a set of rules for defining how different types ofHTML fragments should be laid out and formatted. These HTML fragments are defined in tem-plates using constructs. A construct is an abstract type that WPF matches to a particular type ofHTML fragment and contains one or more elements (or even other constructs) that define howthe HTML should be laid out and formatted. When generating pages, WPF will try and matchHTML fragments with constructs in the template, and if a match is found, the construct’s struc-ture and formatting is applied to the HTML fragment. For example, a construct might define howto display HTML fragments that contain dates, and another construct might define how to displaytables. If multiple matches for an HTML fragment are found, the most specific construct is used.So, if an HTML fragment matches a generic date construct and a date construct for tables, and thefragment is in a table, the construct for dates in tables are used.

Constructs are specified in an HTML template using the following syntax:

<HTMLWRAPPER name=”DisplayPageWrapper”>

</HTMLWRAPPER>

Everything that falls in-between the start and end tag defines how the construct is displayedand structured. Each template is split into two sections: a display section and a data entry section.If a form contains at least one data entry field on it, the data entry section of the template is used;if not, the display section is used.

As a best practice, it is recommended that you don’t try and build an HTML template fromscratch, but rather take a copy of another HTML template, modify it, and link to the copied ver-sion from your builders. WPF provides several master HTML template files by default, which arelocated in the WebContent\factory\html_templates directory of your project. The example at theend of this section demonstrates how you can use this approach to implement a custom HTMLtemplate in the assets application.

Some of the page automation builders that use an HTML template are listed here, alongwith the name of the HTML template used. Note that in addition to inputs for HTML templates,these builders usually have an additional input for page HTML. The difference between pageHTML and HTML templates is that the page HTML presents a container for the HTML output

Working with Web Pages 137

Page 175: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

produced by the builder and contains a tag named ‘data’; WPF replaces the contents of this tagwith the output generated by the builder using the HTML template to structure and format theoutput. Using both inputs together, you can get considerable control over how WPF displays dataand still take advantage of WPF’s automation features. Also, because the templates are stored inHTML files, you can easily share them between different applications.

View & FormThe View & Form builder used in this chapter has several inputs for specifying base HTMLpages, and it also has inputs for HTML templates in the View Page Options and Row Details Sup-port sections. By default, the gridtable.html template is used for both templates to define thestructure and appearance of the view page and detail page.

BreadcrumbsThis builder uses the breadcrumbs.html template to add breadcrumb navigation to an HTMLpage.

TIP

If you open up one of the default templates, you will notice that they already contain sampledata. This data is just used to preview the template and is removed when the template isactually used by WPF (remember that WPF automatically flushes the contents of any ele-ments in an HTML template where the word Container is used in the name attribute).

Data PageThis builder also uses the gridtable.html template to control how it creates HTML.

Data Column Modifier, Data Field Modifier, and Data Hierarchy ModifierAll these builders contain inputs for specifying HTML templates, but no templates are used bydefault. Some useful templates you can use as starting points are the columnar.html and colum-nar_styles.html templates, which each display a basic table containing four columns. The firstcolumn is for a field label (for instance, Name), the second is for indicating whether the field ismandatory, the third is for the actual field value or input, and the fourth is for a validation mes-sage (for instance, ‘This field requires a numeric value’). The templates are identical, exceptcolumnar.html takes its styles from the template_compatible.css style sheet, and columnar_styles.html has all its styles hard-coded into the HTML.

The following example demonstrates how you can use some of the HTML manipulationtechniques discussed. The example adds some HTML to the view page and manipulates theHTML used to display the paging buttons. A custom HTML template is also used to manipulatethe layout of the detail page.

The following builders are added in this section:

• Comment

• HTML

138 Chapter 5 Customizing Portlet Appearance

Page 176: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding HTML

First, add a Comment builder call to the model and name it Using HTML. Save the builder call.This builder serves as an organizational divide in your model between the builders in the previoussection and the HTML builder used in this section. Now, add an HTML builder call to yourmodel. This builder call is used here to insert instructions for opening the detail page after theOuterTable tag, which places the message at the bottom of the screen. Edit the HTML builder sothat it appears, as shown in Figure 5.27, and save the builder call when finished.

Working with Web Pages 139

Figure 5.27 Configuring the HTML builder call.

Modifying the Paging Buttons HTML

Make a copy of the data_paging_buttons.html file, which you can find under the WebContent/factory/pages directory of the assets project, and name the copy custom_data_paging_buttons.html. This page contains the HTML for the page navigation buttons that appear at thebottom of the data table. Modify the HTML as shown by the bolded sections in the followingcode, and then save the file when finished. This removes the style class for the wrapper surround-ing each button, which removes the border from the pagination controls, and centers these con-trols in the middle of the screen.

<!—

This page is imported to form the execution-time UI for the

Paging Buttons Builder. You can replace this with another HTML file

so long as you use the same tag names.

—>

Page 177: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

<!— default style definitions —>

<link rel=”stylesheet” href=”/factory/pages/data_paging.css”></link>

<br>

<span name=”wrapper”>

<table class=”” cellspacing=”0” cellpadding=”0” align=”center”>

<tr>

<td>

<!— target for the “first page” image button —>

<span border=”0” vspace=”0” hspace=”0” class=”” name=”firstbtn” />

</td>

<td>

<!— target for the “previous page” image button —>

<span border=”0” vspace=”0” hspace=”0” class=”” name=”prevbtn” />

</td>

<td valign=”bottom”>

<!— the range of displayed records/pages goes here —>

<span name=”displayed_pages” class=””>

&nbsp;&nbsp; <span name=”range”/>&nbsp;&nbsp;

</span>

</td>

<td>

<!— target for the “next page” image button —>

<span border=”0” vspace=”0” hspace=”0” class=”” name=”nextbtn” />

</td>

<td>

<!— target for the “last page” image button —>

<span border=”0” vspace=”0” hspace=”0” class=”” name=”lastbtn” />

</td>

</tr>

</table>

</span>

Open the Paging Buttons builder call in the Builder Call Editor and scroll down to theAdvanced section. Change the HTML Page input to /factory/pages/custom_data_paging_buttons.html, which uses the newly created HTML as the base HTML page for thenavigation buttons. Save the builder call when finished.

Modifying the gridtable HTML Template

Make a copy of the gridtable.html HTML template, which you can find under the WebContent/factory/html_templates directory of the assets project, and name the new copy custom_gridtable.html. This new template is used to change the layout of the assets detail page. Openthe custom_gridtable.html file by double-clicking on it in the Outline view.

140 Chapter 5 Customizing Portlet Appearance

Page 178: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Working with Web Pages 141

Notice that the file is split into two sections: a display page section and a data entry pagesection. Because the detail page doesn’t contain any data entry fields, you should work withthe display page section, the section at the top of the template delineated by the comment<!-- Begin: Display Page Wrapper -->. Scroll down to the LabelContainer construct, whichappears as follows:

<HTMLWRAPPER name=”LabelContainer”>

This construct displays section labels and contains an element called DisplayGroupLabel,which defines the way section labels are displayed for all HTML output that uses the current tem-plate. Center the contents of the DisplayGroupLabel element by adding an align attribute, asshown in the following bolded code:

<HTMLWRAPPER name=”LabelContainer”>

<tr name=”DisplayGroupLabel”>

<td colspan=”2” height=”25” class=”sectionLabelCell”

align=”center” nowrap><span name=”LabelText”

class=”sectionLabel”>Section Label</span></td>

</tr>

</HTMLWRAPPER>

Scroll down to the DataContainer construct. This construct contains an element called Dis-playField, which defines each table row contained in the DataContainer construct. Each row ismade up of two cells: a label cell and an output data cell. Modify the label cell so that it containstext that is left aligned and succeeded by a space character, which ensures that there is a spacebetween the text and the edge of the cell. You can do this by modifying the bolded parts of theDataContainer construct, as shown here:

<HTMLWRAPPER name=”DataContainer”>

<tr name=”DisplayField” class=”DisplayFieldRow”>

<td class=”labelCell” height=”27” align=”left”valign=”top” nowrap>&nbsp;&nbsp;&nbsp;<span

name=”FieldLabel” class=”label”>Field

Label</span>&nbsp;</td>

<td width=”100%” class=”outputDataCell” valign=”top”>

<span name=”FieldElement” class=”outputData”>Field

Value</span></td>

</tr>

<HTMLWRAPPER>

Save the custom HTML template.

Using the HTML Template

Open the View & Form builder and scroll down to the Row Details Support section. Edit theHTML Template File input in this section so that it points to your new, customized HTML tem-plate. Save the builder call when finished.

Page 179: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Test the assets application now by opening the view page in a Web browser. You should seethe output shown in Figure 5.28. Notice the added prompt at the bottom of the data table on theview page and the modified pagination controls. If you open a detail page for an asset, you shouldsee the modified layout shown in Figure 5.29.

142 Chapter 5 Customizing Portlet Appearance

Figure 5.28 Testing the HTML modifications to the assets view page.

Figure 5.29 Testing the HTML modifications to the assets detail page.

Cascading Style Sheets

Cascading Style Sheets (CSS) is a language that enables you to customize the appearance of indi-vidual elements on a markup page, such as HTML or XML. For example, you can use CSS to setthe font size of a heading in a portlet or change the layout of a table. CSS is cascading becauseyour style directions for a page are cascaded into a single style sheet, based on certain priorities.A style with a higher priority takes precedence over a style with a lower priority. These prioritiesare specified, in order of highest to lowest:

1. Style specified in an HTML element

2. Style specified inline in the HEAD tag of an HTML page

3. External CSS file linked to from an HTML page

4. Default style in Web browser

When creating portlets in WPF, cascading style sheets can be implemented in several ways.Some of the builders that create presentation components have an input to specify a style sheetthat applies to the output produced by the builder; for example, the Data View builder has an input

Page 180: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

called Stylesheet URL for this purpose. This is equivalent to specifying a style sheet in the HEADtag of an HTML page. However, when a style sheet input is not available (as in the case of theView & Form builder), you should use the Style Sheet builder. This builder lets you designate astyle for either an entire page by placing it in the HEAD tag or for part of a page by placing it in aparticular HTML element. The style in the builder can be defined in an external .css file (usuallyin a servable directory under the WebContent directory), imported from an external file, or typeddirectly into the Style Sheet builder. As a third alternative, you can also manually insert CSSstatements directly inside HTML pages as you would in an ordinary Web application. Forexample, you might manually specify an external style sheet using the following HTML:

<link name=”tabbedPagesStyleSheet” type=”text/css”

rel=”stylesheet” href=’http://localhost:10038/

MyWPFApplication/factory/pages/tabb

edPagesStyles.css’>

Style sheets can be used to modify standard HTML elements, such as body and head. Forexample, the body element can be styled as shown here:

body {

color: #000000;

font-family: Arial, Helvetica, sans-serif;

font-size: 12px;

}

You can also create custom style classes, which can then be assigned to particular elements.For example, you could create a tableHead class for your table headings, as shown here:

/** for table head cells**/

.tableHead {

background-color: #DDDDDD;

padding: 3px;

}

You would then associate HTML elements with this style by setting the class attribute ofeach element. For example, to specify that a table head element called ColumnHeader should usethe tableHead style, you would define the element on an HTML page as follows:

<TH name=”ColumnHeader” class=”tableHead”>

This technique applies when you are modifying your own HTML pages directly and whenyou are working with HTML automatically created by WPF. For example, you can modify thestyle sheet used by the builder’s HTML template by making a copy of the HTML template and itsassociated style sheet, modifying the copied style sheet, pointing the copy of the HTML templateto the new style sheet, and then referencing the new HTML template in your builder. Alterna-tively, you can also use a Data Field Modifier builder call to change the attributes of fields whenthey are placed on the page.

Cascading Style Sheets 143

Page 181: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Keep in mind that when working with portlets in WPF, you are working with a table cellwithin an HTML table, which is how portlets are displayed in a portal. As a result, the portal candefine its own styles, as can other portlets within the portal, and these styles might conflict withthe styles in your portlet. Make sure you thoroughly test your portlet styles as they will appear inthe portal before rolling them out into production environments.

The following example shows how to add a Style Sheet builder call to the assets model.This style sheet is used on the asset detail page and overrides the NewsColumnWrapper and labelstyles used for the newspaper column container and the field labels, respectively. For more infor-mation on the default styles, see the “Commonly Used Styles” sidebar in this chapter. Thechanges will specify that the background around the newspaper columns is white instead of darkgray and that the label headings should be bolded.

The following builders are added in this section:

• Comment

• Style Sheet

Adding a Style Sheet

Add a Comment builder call to the model and name it Style Sheets. Save the builder call.Then, add a Style Sheet builder call to your model, and name the stylesheet assetsStyle.Change the Location Type input to ‘In HEAD Tag’ and select assetsDataViewAndForm_DetailsPage from the Page dropdown. This will place the style sheet reference at the top of theasset detail page in the HEAD tag, which enables all elements on the detail page to use it(although the style sheet is inaccessible on the view page). The other option for the Location Typeinput, ‘Explicit page location,’ lets you place the style sheet at a specific tag, so that the style sheetis only available to elements contained within that tag.

By default, the Style Sheet builder expects you to explicitly specify the style sheet in theCSS Source field, although you can modify the CSS Source Type input to point to a style sheetstored in a different location. Fill out the CSS Source input with text shown here and save thebuilder call when finished. This overwrites the NewsColumnWrapper and label classes with thenew custom styles.

.NewsColumnWrapper {

background-color: #FFFFFF;

}

.label {

font-weight:bold;

}

#datapage

{

position:relative;

height:420px;

144 Chapter 5 Customizing Portlet Appearance

Page 182: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

overflow:auto;

margin-left:100px;

margin-top:4px;

margin-right:10px;

margin-bottom:0px;

}

#navigation

{

position:relative;

height:250px;

top:2px;

bottom:0px;

margin-left:10px;

}

COMMONLY USED STYLES

A few of the more commonly used default classes in WPF are listed here.These classes areall defined in the gridtable.css file, which is stored in the WebContent/factory/html_templates directory.You can check what styles are being used for WPF-produced content byviewing the source HTML under the Page folder of the WebApp on the WebApp Tree tab.

displayPageTable—This class defines the table that wraps each data page.

dataEntryPageTable—This class defines the same table when the data page is inedit mode.

gridTable—This class is also used in data page tables, and defines the background colorand borders of the table.

tableHeadRow, tableHead, and tableHeadText—These classes define the style for theheading row of a data table, the individual heading cells, and heading text, respectively.

tableRowOdd, tableRowEven—These classes define the styles for odd and even rows,respectively.

outputData, outputDataCell—These classes define styles for input fields or displayedvalues in a data table, and for the cells that contain them.

sectionLabel, sectionLabelCell—These classes define styles for section labels and thecells that contain them. Section labels are used to label groups of input fields and displayedvalues in a data table.

label, labelCell—These classes define styles for labels used to identify input fields anddisplayed values in a data table, in addition to the cells that contain them.

requiredPrompt—This class defines the style of mandatory fields on a form.

errorMessage—This class defines the style used by error messages produced by thedefault WPF validation mechanism. Validation is discussed in Chapter 11.

Cascading Style Sheets 145

Page 183: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

If you test your application now, you should see that the style of the details page haschanged. Figure 5.29 showed the details page for Subcontractor Agreement before the style sheetchanges, and Figure 5.30 shows the same details page after the changes (you can toggle betweenboth styles by alternately disabling and enabling the Style Sheet builder call).

146 Chapter 5 Customizing Portlet Appearance

Figure 5.30 After adding style sheet changes.

Summary

In this chapter, you learned how to arrange and manipulate the appearance of data in a portletusing WPF. You created a simple WPF application to surface information from an asset manage-ment system, which contained a model that was made available as a portlet. In the course of cus-tomizing the interface of this portlet, you used several WPF builders and learned about howHTML templates are used.

The next chapter discusses how you can improve your portlet interfaces by adding variouscontrols to the page, such as buttons and links.

Important Points

• WPF can use HTML, XML, JSP, and JavaScript to produce its output. WPF developersnormally use a combination of builders and traditional Web artifacts (for instance, stylesheets) to control how this information is arranged and displayed in a portlet.

• Data can be paginated in WPF using a paging assistant, which is automatically createdby several builders. To create an interface for users to cycle between pages, a PagingButtons or Paging Links builder should be used in conjunction with the paging assistant.

• The View & Form and Data Page are commonly used to display data on the screen. TheView & Form is particularly well suited to data that is in a list and detail format.

• The Data Column Modifier, Data Hierarchy Modifier, and Data Field Modifier are com-monly used to manipulate the properties of fields on a page. The Data Field Modifiergives you a lot of control over individual fields, and the Data Column Modifier and DataHierarchy Modifier are more useful for organizing fields on a page. The Rich Data Defi-nition builder is also commonly used for controlling the display of data, and is particu-larly useful for field validation, formatting, and translation. The Rich Data Definitionbuilder is discussed in Chapter 11.

Page 184: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• It is recommended that HTML pages and JSPs are inserted into models using theImported Page builder, which makes your pages easier to share between projects. ThePage builder is useful for building small HTML pages that don’t need to be shared. Youcan view the generated pages for a model by navigating to the WebApp Tree tab of theEditor window.

• Builders that produce HTML output can insert content in relation to named tags on apage. <span> tags are the most commonly used tag for this purpose.

• Builders that produce HTML output usually have two types of HTML input: one forpage HTML and the other for a HTML template. Page HTML is the surrounding HTMLfor the output of a builder, and an HTML template is used to arrange and format theresults of the builder inside the page HTML.

• Cascading Style Sheets can be implemented in WPF using the Style Sheet builder andby configuring certain builders that support this functionality, such as the Data Viewbuilder. More traditional methods for defining styles, such as adding style sheet refer-ences to an HTML page directly, are also available.

Important Points 147

Page 185: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 186: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

149

C H A P T E R 6

Adding Basic UserInterface Controls toYour Portlets

User Interface (UI) controls such as text boxes, buttons, and checkboxes are an integral part ofany portlet, as they are the means by which people interact with your applications. This chapterdiscusses how you can expedite the process of adding basic UI controls to portlets via the pre-packaged builders in WebSphere Portlet Factory (WPF). By the end of this chapter, you will beaware of some useful techniques for automating UI development, and you will also have con-structed a simple survey form to demonstrate these techniques. The survey form will be surfacedto a portal server as a portlet.

The model used in this chapter is available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 6 folder (instructions for copying this file into your project areincluded in a readme.txt file in the same folder); however, to increase your understanding of thetopics discussed in this chapter, it is recommended that you create the models yourself by follow-ing the example in this chapter. Two image files are also used in this example; you can downloadthese images from the images directory in the Chapter 6 folder or, alternatively, you can use yourown image files (the dimensions for the images are given later in the chapter).

The following topics are covered in this chapter:

• User interface controls in WPF

• Creating a survey portlet

User Interface Controls in WPF

A number of builders in WPF can be used to automate the process of adding and manipulating UIcontrols on a portlet page. These builders automatically insert particular UI elements at specifiedtags in your portlets (the <span> tag or <input> tag is normally used), and WPF provides you witha graphical interface for manipulating the settings of these controls. This automation makes your

Page 187: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

portlet interfaces easier to maintain and can help to standardize the appearance of HTML in yourportlets. For further tweaking of these controls, and to add controls that are not provided by thedefault WPF builders, you can also declare and configure the controls directly in the HTML (asyou would in ordinary portlet development). If you find that you are often adding the same customcontrols to your pages, then you may find it useful to encapsulate these controls in a custombuilder, which will enable you to automate the use of these controls to varying degrees. Custombuilders are discussed in more detail in Chapter 15, “Performance and Process Optimization.”

Because there are several options available to you when adding UI controls in WPF(prepackaged builders, HTML controls, custom builders, and combinations of all three), there areusually multiple ways to achieve the same task. There is no real right or wrong way of goingabout designing a UI in WPF, but it is still a good idea to come up with a standard procedure forinterface design (particularly when multiple people work on the same projects). As a best prac-tice, it is generally better to use prepackaged WPF builders wherever possible, as this requires theleast development effort to implement, is easy to maintain due to the wizard-based interface ofthe builders, and the builders have already been tested by the WPF development team.

When you need UI functionality that is not provided by the default builders, you can add itdirectly into the HTML as required. If you think this functionality can be automated to somedegree, you can include the functionality in a custom builder, but keep in mind that the timerequired to develop one of these builders is significantly more than the time taken to add the con-trols directly into the HTML. However, it is only a once-off development effort, after which thebenefits are that your controls will be easier to maintain and you can standardize the way yourHTML is created. Also, for more complicated controls, using a custom builder rather than manu-ally manipulating HTML can help to minimize human error and will often save you time in thelong run.

If you have completed the examples in the book up to this point, you already have seensome of the ways you can automatically add UI controls to a page using WPF (using, forexample, the View & Form builder). WPF also contains builders for adding basic UI controls to apage, and the example application in this chapter demonstrates the use of the basic UI controlbuilders. The example utilizes one model, which displays a list of survey questions and allowsthese questions to be submitted. Once submitted, a results page is shown and the user’s inputs aredisplayed on the screen.

The example in this chapter is a convenient way to demonstrate WPF’s basic UI builders,but note that when working with large forms, it is often easier to define your form fields in anXML document, and then use a Data Page and Rich Data Definition to create form fields based onthe XML. You can still use the builders discussed in this chapter to customize these fields (byoverwriting the contents of the desired tags), and also to create additional UI controls not relatedto the form fields themselves (such as OK buttons and site navigation links). The Data Page is dis-cussed in Chapter 5, “Customizing Portlet Appearance,” but first appears in an example in Chap-ter 7, “Communicating Between Portlets.” The use of the Rich Data Definition and Data Pagetogether is demonstrated in Chapter 11, “Field Validation, Formatting, and Translation.” Also, for

150 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Page 188: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

information on more advanced UI control builders than the ones in this chapter, see Chapter 13,“Using Ajax and Dojo.”

Creating a Survey Portlet

In this section, you build a portlet to test some of the UI controls available in WPF. The portletconsists of two screens. The first is a survey form for a fictional product (the mysterious productX) and enables users to submit their answers to the portal server (a screen shot of this portlet isshown later in Figure 6.5). The answers are not processed or validated in any way, but they aredisplayed to the user on the second screen, which is a confirmation page to let the user know thatthe survey was submitted successfully. Validating, translating, and formatting are covered inChapter 11.

Before you proceed with this section, you need a WPF project to house the survey model. Ifyou have a project from a previous chapter, then you can use it; otherwise, you should create anew WPF project (for more information on creating projects, see Chapter 1, “Introduction to Web-Sphere Portlet Factory”). The project will be published as a WAR file and deployed to a portalserver, and you should also deploy the application to a local application server for testing. You canuse the portal server if it runs on your local machine; otherwise, it is recommended you use theIBM WebSphere Application Server Community Edition server (WAS CE) that comes with WPF.

After you have a project set up, you need to add a model for the survey portlet. For the firstpage in the survey form, you need the following builders:

Creating a Survey Portlet 151

• Portlet Adapter

• Action List (x2)

• Comment

• Page

• Text Input

• Calendar Picker

• Select

• Radio Button Group

• Checkbox Group

• Text Area

• Check Box

• Hidden Input

• Variable

• Button

Note that although the order of builder calls is usually not important, occasionally the orderof your builder calls can create errors or warnings in your application. The order of the buildercalls used in this chapter can be changed if desired; the present order is intended to group buildercalls according to the page they belong to, in roughly the same order that they will be used on thepage.

Creating a Model

Create a new model called survey in your project, under the folder WEB-INF/models/chap-ter06. The model should be based on the Main and Page template, using a Page Type of SimplePage. For more information on creating models, see the example in Chapter 1. After it is created,

Page 189: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

your model should have two builders in it: an Action List called main and a Page called page1.The Action List runs automatically whenever the model is run and opens the page1 Page.

Modifying the Page

Open the Page builder. Delete the contents of the Page Contents (HTML) input and enter the fol-lowing HTML instead:

<html>

<body>

<form name=”surveyForm” method=”post”>

<div align=”center” style=”font:12pt Arial;font-weight:

bold;color: #336699;”>Product X Survey</div>

<br>

<br>

<table cellpadding = 10>

<tr><td>What is your email address?</td><td><span

name=”answer1”></span></td></tr>

<tr><td>When did you start using Product

X?</td><td><span name=”answer2”></span></td></tr>

<tr><td>How many times a week do you use product

X?</td><td><span name=”answer3”></span></td></tr>

<tr><td>How do you rate product X?</td><td><span

name=”answer4”></span></td></tr>

<tr><td>When do you use product X?</td><td><span

name=”answer5”></span></td></tr>

<tr><td>Additional comments:</td><td><span

name=”answer6”></span></td></tr>

<tr><td></td></tr>

</table>

<br>

<span name=”answer7”></span>

<br>

<span name=”createdDate”></span>

<br>

<span name=”submitButton”></span>

</form>

</body>

</html>

This creates a survey form that has a table consisting of six questions and six answers. Theanswers are span tags that will be replaced with UI controls from WPF. A seventh answer appearsoutside the table—this is replaced with a checkbox. The checkbox is outside the table because itstext is long and would otherwise drag out the width of the first table column. Note that there is noquestion included for answer7, as the question is included as part of the checkbox field. Finally,

152 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Page 190: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

the submittedDate span tag is used to place a hidden control (which is submitted with the formbut won’t be displayed to the user), and the submitButton is replaced with a button from WPF thatenables users to submit their answers.

Save the builder call when you are finished.

TIP

There are numerous ways to build forms using WPF. Many of the other chapters in this bookuse the various data display builders in WPF for this purpose, such as the Data Page andView & Form builders, which help to automate the process of form construction. Theapproach adopted in this chapter (that is, explicitly specifying fields on an HTML page)demonstrates an alternative approach that may be preferable in certain scenarios, such aswhen you don’t have a data set to base your field inputs on or when you want to control thelayout of your fields directly in the HTML. Note that you can also change the layout of gener-ated HTML using the data display builders (see Chapter 5 for more information about this),but explicitly specifying fields in the HTML might be quicker for simple forms that are notintended to be reused elsewhere.

Note that the techniques used in this chapter can also be used to replace the results ofthe data display builders (by specifying the appropriate tags that you want to overwrite).

Adding a Portlet Adapter

The first builder call to add is a Portlet Adapter, which surfaces your model as a portlet when theapplication is deployed to a portal server. Select Portlet Adapter from the Builder Palette (you canopen the Builder Palette by clicking the icon in the Outline view) and pressing OK. Name thePortlet Adapter survey, change the Portlet Title to Survey Form, and then change the PortletDescription to This portlet displays a survey form for Product X. This surfacesthe survey model as a portlet called Survey Form. Save the builder call when you are finished.

Organizing Builders for page1

Add a Comment builder call to the model and name it page1. This helps separate out the buildercalls in your model and denotes the purpose of the builder calls that follow it. Save the buildercall so that it displays in Outline view, and then drag it so that it displays above the page1 buildercall. Also, drag the Portlet Adapter builder to the top of the model, and save the model when youare finished.

The next few builder calls contain functionality for the first page in the model (that is,page1, the survey form itself).

Adding a Text Input

The next step is to add UI controls to the form, so that users can answer the survey questions. Thefirst control is an input for an answer to the first question, “What is your email address?” Theanswer is a single line of text, so you can use the Text Input builder to place a text box onto the

Creating a Survey Portlet 153

Page 191: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

screen. Add a Text Input builder call to the model and name it answer1. Specify the Page aspage1 and the Tag as answer1, and then save the builder call.

Adding a Calendar Picker

The second control is an input for the answer to the first question, “When did you start usingProduct X?” The answer is a date value, so the input field requires a text box with a calendarpicker. The user can either type in the date manually or use the calendar picker to choose a date.When a user clicks on the calendar picker, a JavaScript calendar is temporarily displayed. Fromit, the user can select a particular date. The user’s selection is then sent back to the underlyingform.

Add a Calendar Picker builder call to the model and name it answer2. Specify page1 andanswer2 as the Page and Tag in the Page Location section, and then expand the PopUp Calendarsection. The JavaScript calendar can be accessed through two different buttons: The first islabeled with an ellipsis (…), and the second is labeled with an image (by default, the image is acalendar, although you can change it from the Button image input. Note that you can also changethe images used when the button is hovered over and when it is pressed). Change the Button Typeinput to image and save the builder call.

Adding a Drop-Down Select Box

The next question, “How many times a week do you use product X?,” requires that the userchoose from a preset group of answers. To handle this, a drop-down box will be added to the formwith the Select builder. Add a Select builder call to the model and name it answer3. Specify thePage as page1 and the Tag as answer3. In the Select Data input, enter the following comma-separated list of values:

Less than 3,4-6,7 or more

This adds three possible options to the drop-down for answer3. Note that the Lookup Tableinput enables you to retrieve this information via a lookup table rather than specifying it directlyinside the builder call. For an example of how to use lookup tables, see Chapter 4. Save thebuilder call when you are finished.

Adding a Radio Button Group

Now, add a Radio Button Group builder call to the model. This provides a group of radio buttonsfor the answer to question 4, “How do you rate product X?” The possible answers are Terrible,Poor, Average, Good, and Excellent.

Name the builder call answer4, and specify page1 and answer4 as the Page and Tag,respectively. For the Radio Group Input field, enter the following comma-separated list of values:

Terrible,Poor,Average,Good,Excellent

Finally, scroll down to the Selected Value input at the bottom of the builder call and typeAverage (the Average option is then selected by default). Save the builder call when you arefinished (note that it is also possible to implement this solution using the Radio Button builder,

154 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Page 192: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

which gives you more control over how the radio buttons are laid out on the page. For more infor-mation on the Radio Button builder, see the “The Radio Button Builder” sidebar).

THE RADIO BUTTON BUILDER

To implement radio buttons, you can either create them by using a Radio Button Groupbuilder or utilize existing radio buttons (that is, ones already defined in the HTML) by using aRadio Button builder. The advantage of the Radio Button builder over the Radio ButtonGroup builder is that you can specify the format of the radio buttons inside the HTML.

For example, to implement radio buttons for the answer to question 4, you could specifythe HTML for the radio buttons along the following lines:

<td>

Terrible <input name=”answer4” type=”radio” value=”1” />

Poor <input name=”answer4” type=”radio” value=”2” />

Average <input name=”answer4” type=”radio” value=”3” />

Good <input name=”answer4” type=”radio” value=”4” />

Excellent <input name=”answer4” type=”radio” value=”5” />

</td>

After this is done, you can add a Radio Button builder to your model, pointing the Tag toanswer4. Note that you can modify how the options appear simply by modifying the HTML(for example, you can make the options display in two columns by inserting another tablecell, or on separate lines by inserting <br> tags).

Adding a Checkbox Group

The next builder call to add is a Checkbox Group, which provides a group of checkboxes foranswers to the question, “When do you use product X?” The possible answers are Walking, Run-ning, Cycling, and Swimming.

Add a Checkbox Group builder call to the model and name it answer5. Enter the Page andTag as page1 and answer5, respectively. For the Checkbox List Data input, enter the followingcomma-separated list of values:

Walking,Running,Cycling,Swimming

Save the builder call when you are finished. (Note that you can also add a single checkboxto a form using the Checkbox builder. This will be done for answer7 later in this section.)

Adding a Text Area

You now need a text box for the user to enter some additional comments (answer6). Because theanswer may take up several lines, you should use the Text Area builder rather than the Text Inputbuilder, as this will enable you to place a text box with several rows (scroll bars will be displayedif the user types in more characters than what can be displayed in the text box at one time).

Creating a Survey Portlet 155

Page 193: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Add a Text Area builder call to the model and name it answer6. Specify the Page and Tagas page1 and answer6. Now expand the Attributes section and enter 50 for the Cols input and 3for the Rows input. This creates a text input with three rows of 49 characters (the space for the50th character will be taken up with a vertical scroll bar). Change the Wrap input to Virtual;this wraps the text in the text box when the user types more than 49 characters, but won’t insertany new line characters in the text that is submitted to the server when the user submits the form.Save the builder call when you are finished.

Adding a Checkbox

For the final answer input, add a Checkbox builder call to the model and name it answer7. Thisadds a single checkbox control to the form, which the user can enable if he wants to receive infor-mation about special offers and promotions.

Enter page1 and answer7 for the Page and Tag inputs, and then type I would like toreceive information about future promotions and special offers for the Labelinput. Save the builder call when you are finished.

Adding a Hidden Input

The next builder call adds a hidden input to the form to hold the value of the date and time atwhich the form was created for a given user. Although this input will not be displayed on thescreen, it is still submitted when the form is submitted. This is particularly useful for sendingdiagnostic information to the server that is unnecessary to display on the screen.

Add a Hidden Input builder call to the model and name it createdDate. Specify the Pageand Tag as page1 and createdDate, and then type the following line for the Value input:

${Java/java.util.Calendar.getInstance().getTime()}

This is inline Java code that populates the hidden input with the results of a method call,accessed via a Java utility class called Calendar. For more information on using Java in WPF, seeChapter 8, “Using Java in Portlets.” Save the builder call when you are finished.

TIP

You can also hide inputs by setting the type HTML attribute of the field to hidden (using anAttribute Setter or Data Modifier builder). This has the same effect as the Hidden Inputbuilder, although the type attribute is not supported by every WPF control (such as the textbox created by the Text Area builder). Alternatively, you can use the Visibility Setter builder tohide fields. The Visibility Setter enables you to hide tags based on certain conditions (suchas a particular value being true); however, fields hidden by a Visibility Setter are not accessi-ble as request inputs (that is, the values of these fields are not submitted when the form issubmitted).

Visibility Setters can also be used in conjunction with partial page refreshing to dynami-cally hide and show parts of a form without reloading the entire page (for an example ofhow to do this, see Chapter 13).

156 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Page 194: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Variable to Store User Inputs

Now, add a Variable builder call to the model and name it formInputs. Change the Type input toString and save the builder call. This builder call creates a String variable called formInputs,which you can use to store the user’s submitted values (and then display them on the confirmationpage).

Defining Actions for Submitting a Survey

Next, add an Action List builder call to the model. This Action List defines the sequence ofactions to execute when the survey form is submitted. Two actions are required: The first is set thevalue of the formInputs variable based on a text representation of the user’s answers, and the sec-ond action displays the confirmation page.

Change the name of the builder call to submitAction, and then open the Select Actiondialog by clicking the ellipsis button to the right of the first row in the Actions input. SelectAssignment from the Special menu (as shown in Figure 6.1), and then press OK. This lets youassign a particular source value to a target field. Specify Variables/formInputs as the Target. Forthe source value, you should specify a string representation of the request inputs, which you cando by using another inline Java statement:

${Java/webAppAccess.getRequestInputs().toString()}

Press OK to accept the assignment and return to the Action List builder call.

Creating a Survey Portlet 157

Figure 6.1 Setting the first action for the submitAction Action List.

Page 195: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

The inline Java statement in this section represents all of the request inputs in a concate-nated string. This is useful for debugging purposes, but it is cumbersome if you want to beable to access and process individual inputs.You can access an individual request input byusing the following syntax, where requestInput is the name of a request input (for example,answer1):

${Inputs/requestInput}

For the second action in the Action List, type page2. This opens the confirmation page,which you create in the next section. Save the builder call when you are finished.

Adding a Button

The last builder call to add for page1 is a Button builder call, which gives users a means to submitthe form. Add a Button builder call to the model and name it submitButton. Specify page1 andsubmitButton as the Page and Tag, and then type Submit for the Label input. Change the Actioninput to submitAction; this causes the Action List created in the previous step to be run whenthe button is pushed. Notice that the Action Type input is set to ‘Submit form and invoke action,’which will cause the values of the input fields to be sent to the request object so that they areaccessible in the submitAction Action List.

Save the builder call when you are finished. You have now finished the interface for page1.

Organizing Builders for page2

Add another Comment builder call to the model and name it page2. The next few builder callscontain functionality for the second page in the model, which displays a confirmation message tothe user. The users’ inputs from the first page will also be displayed.

To create the interface for the confirmation page, you need to add the following builders:

• Comment

• Page

• Image

• Text

• Link

• Image Button

Adding a Confirmation Page

Add a Page builder call to the model and name it page2. This creates a page called page2 that canaccessed when the survey form is submitted. The page displays a confirmation message andshows the user’s answers from the first page.

158 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Page 196: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Delete the contents of the Page Contents (HTML) input, and then enter the followingHTML in its place:

<html>

<body>

<div align=”center”><div style=”font:12pt Arial;font-

weight: bold;color: #336699;”>Thank you!</div>

<br>

Your answers have been submitted.

<br>

<br>

<span name=”submittedImage”></span>

<br>

<br>

Your answers: <span name=”results”></span>

<br>

<br>

<span name=”back”></span>

</body>

</html>

Save the builder call when you are finished. Notice that this page contains several spantags; these tags will be overwritten with various UI controls in the next few steps.

Adding an Image Builder

The first control to add to page2 is an image that will display under the confirmation text. Theuser will not be able to interact with the image, as it is intended to simply improve the appearanceof the page. If you want users to interact with images, use the Image Button builder, which youadd at the end of this section.

Before you can display an image in the model, you need to add the image file to yourproject. Create a directory called images in the WebContent directory of your project, and thencopy in the back.jpg and submitted.jpg files (you will use the back image later in this section).These files are available for download from the images directory under the Chapter 6 folder atibmpressbooks.com/title/9780137134465. If you can’t download these files, simply create yourown images using the same filenames, and put them into the WebContent/images directory. (Theback.jpg should be fairly small—about 14×14 pixels. The submitted.jpg should be larger, as it isa centerpiece for the confirmation screen. The image used in the example is 116×153 pixels.)

Add an Image builder call to the model and name it submittedImage. Enter the Page andTag as page2 and submittedImage, respectively, and then specify the Image Source input as/images/submitted.jpg. Save the builder call. This adds the submitted.jpg image to page2 atthe submittedImage tag.

Creating a Survey Portlet 159

Page 197: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Displaying Submitted User Inputs

Now add a Text builder call to the model. This builder call places the values of the user’s inputson the survey form into a static, non-editable text field on page2. Name the builder call dis-playResults, and then specify page2 and results as the Page and Tag inputs. For the text input,specify ${Variables/formInputs}, which displays the contents of the formInputs variable inthe text field. Save the builder call.

Adding a Link

Add a Link builder call to the model and name it backLink. This places a link on the page thatenables users to return to the survey form. Change the Page and Tag inputs to page2 and back,respectively, and then type Return to the question page for the Link Text. Specify page1as the Action, and change the Action Type input to ‘Link to an action.’This simply runs the appro-priate action (opening page1) without submitting the form (as there is no form on page2, only onpage1). Save the builder call when you are finished.

Adding an Image Button

Finally, add an Image Button builder call to the model. This can be used to place a clickableimage button next to the back link, so that users can click on the image or the link to return to thesurvey form. Change the name of the Button to backButton, and then change the LocationTechnique input in the Page Location section to ‘Relative to named tag.’This enables you to placethe button before the backButton tag. Specify page2 and back for the Page and Tag inputs, andthen change the Placement input to ‘Before.’ Type the New Tag Name as backButton.

Under the Image Sources section, type /images/back.jpg for the Image input to link tothe image file you added earlier. Note that you can also specify separate images in this section forwhen the mouse is hovered over, and for when the button is clicked. Leave the defaults for theseinputs, and then enter page1 into the Action input at the bottom of the builder call. This returns tothe survey form when the button is pressed.

Save the builder call when you are finished. The survey portlet is now complete. The next section describes how you can test the various

UI controls in the survey portlet from your IDE.

Testing the Survey Portlet

To test the survey portlet, run the survey model from the WPF Designer by clicking the iconon the toolbar. This runs the currently active model (survey) with the last run configuration youused. If you have not set up a run configuration before, you will be prompted to do so—create anew configuration under the WebSphere Portlet Factory Model category (if you want more infor-mation on setting up a run configuration, see the “Testing the Application” section in Chapter 1).

The Product X survey form should load as shown in Figure 6.2.

160 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Page 198: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 6.2 The Product X survey form.

Enter your email address into the first field, and then enter a date value into the secondinput by pressing the Calendar icon to the right of the text box. You should see a popup JavaScriptcalendar, as shown in Figure 6.3. After you select a date and press OK, it should update the under-lying form with that date.

Testing the Survey Portlet 161

Figure 6.3 The Calendar control.

Page 199: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Press the arrow in the drop-down box for question 3 (“How do you rate product X?”), andyou should see a list of three options available. Select an option and proceed to the next question.

Rate product X on the scale provided for question 4, and then click one or more boxes forquestion 5 (“When do you use product X?”). After you have finished this, enter some text into theAdditional Comments text box. Finally, enable the checkbox to receive information about futurepromotions and special offers.

Press the Submit button when you are finished. This submits all of your answers and copiesthem into the formInputs variable.

You should now see a confirmation page, as shown in Figure 6.4. Notice that all of theanswers from the first page are displayed, including an additional input for createdDate (this wasthe hidden input you created on the survey form). The layout of the page is very basic (and notoverly pretty), but it does display the values entered using the UI controls on page1. As men-tioned earlier in the chapter, if you wanted to process these inputs, you could use the ${Inputs/requestInput} syntax for each input; for example, the action ${Inputs/answer2} wouldretrieve the user input for answer 2. Also, note that for large numbers of fields, it is usually easierto define your data in an XML document, and then display a form to edit this data using WPFbuilders like the Data Page and Rich Data Definition (the Data Page is first used in Chapter 7, andthe use of the Data Page and Rich Data Definition together is discussed in Chapter 11).

162 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Figure 6.4 The confirmation page.

Click the ‘Return to the question page’ link to return to the survey form.When the survey form loads, press the Submit button again. All of the inputs are blank, but

you just want to test the Image button on the confirmation page to ensure it will also return you tothe survey form page.

When the confirmation page loads, click on the back image next to the ‘Return to the ques-tion page’ link. You should be returned to the survey form. After you have tested the survey

Page 200: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

model, you should rebuild your application on the portal server (for instructions on how to dothis, see the example in Chapter 1), after which you will be able to view the survey model as aportlet on the portal server. After you have added the survey portlet to a page in the portal, itshould display as shown in Figure 6.5.

Summary 163

Figure 6.5 The survey portlet.

Summary

In this chapter, you learned about some of the different builders in WPF that can be used to addUI controls to portlets, and you also built a simple survey portlet using these builders. The portletconsisted of a survey form, which displayed a number of questions about Product X, and a confir-mation page, which displayed when the survey form was submitted.

Later in this book, you look into some of the other ways that WPF can be used to create UIcontrols. In particular, the Rich Data Definition builder (discussed in Chapter 11) can be used to

Page 201: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

add controls for fields taken from an XML document, and the Ajax and Dojo builders that comewith WPF can be used to add more powerful UI controls to your applications (these controls arediscussed in Chapter 13). It is not necessary that you complete the chapters in this book in order,so you can skip ahead to these chapters if you want.

The next chapter, “Communicating Between Portlets,” discusses some of the differentways to send information between portlets in WPF.

Important Points

• Although you can add UI controls to an HTML page in the same way that you can inordinary Web development, you can also use WPF builders to add and configure some ofthe more commonly used controls.

• The Calendar Picker builder can be used to add a text field with a popup JavaScript cal-endar to a portlet page.

• The Text Input and Text Area builders can be used to add text boxes to a page. The TextInput builder should be used when only one line of text is required; the Text Area buildercan be used for multiple lines of text. Also, the Text builder can be used to place statictext at a given location on a page.

• The Select builder places a drop-down text box onto a page.

• The Radio Button Group builder can be used to place radio buttons onto a portlet page.The Radio Button builder can be used to replace existing radio buttons with WPF radiobuttons; this is useful because it lets you manipulate the appearance of the radio optionsin the underlying HTML.

• The Checkbox Group builder can be used to place a list of checkboxes onto a page. TheCheckbox builder places a single checkbox onto a page.

• The Hidden Input can be used to place an invisible input onto a form. The values of hid-den inputs are still submitted when the underlying form is submitted, but they are notdisplayed to the user.

• The Button builder places a clickable button onto a page. Also, the Link builder can beused to place a hyperlink on a portlet page.

• The Image builder can be used to place an image on a page. The Image Button buildercan be used to place a clickable image onto a page, which executes a particular actionwhen clicked.

164 Chapter 6 Adding Basic User Interface Controls to Your Portlets

Page 202: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

165

C H A P T E R 7

CommunicatingBetween Portlets

The ability to send information from one portlet to another adds considerable flexibility to yourportlet applications, in both the way they are designed and in the way they are used. This chapteroutlines the numerous ways that you can implement inter-portlet communication using Web-Sphere Portlet Factory (WPF). By the end of this chapter, you will understand the strengths andweaknesses of each approach and will have built a library loans portlet application to demonstratethem.

Each of the models in this chapter is available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 7 folder (instructions for copying these files into your projectare included in a readme.txt file in the same folder); however, to increase your understanding ofthe topics discussed, it is recommended that you create the models yourself by following throughthe example in this chapter.

Note that the example in this chapter does not go into detail about the service/provider con-sumer pattern; for more information on this pattern and on services in general, refer to Chapter 2,“Providing and Consuming Services.”

The following topics are covered in this chapter:

• The benefits of inter-portlet communication

• The WebSphere Property Broker

• Creating a project

• Creating a service provider

• Creating a list portlet

• Creating a detail portlet

Page 203: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• Configuring the WebSphere Property Broker

• Alternative communication methods

• When to use inter-portlet communication

The Benefits of Inter-Portlet Communication

Working inter-portlet communication into your applications has several benefits from both adesign perspective and a usability perspective. Some of the key benefits are listed below.

ExtensibilityInter-portlet communication makes your applications easier to extend and plug into other appli-cations. For example, a portlet that displays a list of loans for a library database might allow usersto click on a particular loan, and then send a loan ID off to other portlets to perform an appropri-ate action. One portlet might be used to display details for the loan, and another portlet might dis-play a chart of overdue loans for the borrower. In this example, you could develop additionalportlets that interact with either portlet, without having access to the source code for the loansportlets.

MaintainabilityInter-communicating portlets are easier to maintain because you can develop or modify a portletwithout making changes to others, assuming that you do not change the nature of the content thatis communicated. For example, you can change the user interface and services in the loans listportlet without worrying about affecting the loan detail portlet.

UsabilityBecause the interface for applications that use inter-portlet communication can be spread acrossseveral portlets, inter-portlet communication can be beneficial for users. Depending on theiraccess rights, users can drag and drop these portlets around the portal page to suit their personalpreferences, and they can add and remove portlets to further customize the interface to theirapplication.

The example application discussed in this chapter demonstrates inter-portlet communica-tion for a simple library system between a portlet listing library loans, and another portlet dis-playing details on an item in the list. The application utilizes three models: a list model, a detailmodel, and a service provider model. The list model is surfaced to a portal server as a portlet anddisplays the list of loans. The detail model is also surfaced as a portlet and displays details for aloan selected in the list model. Finally, the service provider provides the list and detail data for thelist and detail models, which is stored in an XML document.

TheWebSphere Property Broker

JSR-168 portlets do not natively support inter-portlet communication, but portlets can still com-municate with each other in WebSphere Portal Server using a mechanism called the WebSphere

166 Chapter 7 Communicating Between Portlets

Page 204: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Property Broker. The Property Broker is the preferred method of inter-portlet communication inWebSphere Portal, and it is the first communication method demonstrated in this chapter.

TIP

JSR-168 is a standard set of Java APIs for developing portlets.You can and should specifyyour WPF portlets as JSR-168 by selecting Java Standard for the Portlet API setting in yourportal server deployment configuration. The Property Broker receives properties fromportlets, such as a loan ID or success flag, and then publishes these properties for the restof the portal to use. Target portlets can then access these properties and define actions torespond to property changes. After you have deployed your portlets in WPF, you then usethe portal administration interface to set up a link between a property in a source portletand a property in a target portlet. This process is known as wiring two portlets together.

The WebSphere Property Broker can facilitate communication between portlets in differentapplications, and also between portlets that were built using different development tools. Forexample, a WPF portlet can send information to a standard Java JSR-168 portlet, and vice-versa.This makes it easy to maintain and extend your applications, and other developers can writeportlets that communicate with your portlets without needing access to the source code.

The first few sections in this chapter focus on using the WebSphere Property Broker to setup inter-portlet communication between a library list portlet and a library detail portlet. The“Alternative Communication Methods” section then outlines some potential alternatives for com-municating between portlets.

Creating a Service Provider

To provide data to your list and detail portlets, you should create a service provider model. Thismodel will contain operations to retrieve a list of loans and retrieve details on a particular loan,which is consumed by the list and detail models. The service provider is the singular access pointfor loans information in your application, and it makes your application easier to maintain.

Before you can begin the steps in this section, you need a WPF project, which houses theservice provider model and the other models in this chapter. If you have a project from a previouschapter, you can use that. If you don’t, you should create a new WPF project. For more informa-tion on creating projects, see Chapter 1, “Introduction to WebSphere Portlet Factory.” The projectis published as a WAR file and deployed to a portal server, and you should also deploy the appli-cation to a local application server for testing. You can use the portal server if it is running on yourlocal machine. If not, it is recommended that you use the IBM WebSphere Application ServerCommunity Edition server (WAS CE) that comes with WPF.

After you have a project set up, you need to add the service provider model. The serviceprovider uses the following builders to provide its functionality:

Creating a Service Provider 167

Page 205: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• Service Definition

• Variable

• Simple Schema Generator

• Action List

• Method

• Service Operation (x2)

Note that although the order of builder calls is usually not important, some of the buildercalls in this chapter need to be in a specific order. This is because some of the builder calls requirecertain things to be built by the time their build methods run when the WebApp is regenerated. Inthis example, the Variable builder call must precede the Simple Schema Generator builder call tocreate a schema based on the variable built by the Variable builder call, and the Simple SchemaGenerator must precede the Service Operations because the Service Operations require theschema to use for their results. Also, the Action List must precede the first Service Operation, andthe Method must precede the second Service Operation, or you will get errors indicating thatthese resources are unavailable.

Creating a Model

Create a new model called loansService in your project under the folder WEB-INF/models/chapter09. Because you will store your data in an XML variable, rather than get it from a data-base, you need to create the service provider manually. To do this, the model should be based onthe Empty template, which creates a model with no builder calls in it. For more information oncreating models, see the example in Chapter 1.

Defining the Service

Add a Service Definition builder call to the model by selecting Service Definition from theBuilder Palette. You can open the Builder Palette by clicking the icon in the Outline view.Then, press OK. Name the builder call loansService and expand the Testing Support section atthe bottom of the builder call, and then enable the box for Add Testing Support. WPF now auto-matically generates test pages for the operations in your service every time the model isregenerated. Save the builder call when you are finished.

Adding Loan Data

The next step is to add your sample data for the service provider. Add a Variable builder call to themodel and name it loans. Change the Type input to XML and enter in the following XML intothe Initial Value input:

<Loans xmlns=”http://com.ibm.CooperativeExample”>

<Loan>

<LoanID>00001</LoanID>

168 Chapter 7 Communicating Between Portlets

Page 206: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

<Item>The Gullible Traveler</Item>

<LoanedTo>Malcolm Johnson</LoanedTo>

<DueDate>11/05/2007</DueDate>

</Loan>

<Loan>

<LoanID>00002</LoanID>

<Item>A Traveling Aunt</Item>

<LoanedTo>Samuel Russell</LoanedTo>

<DueDate>11/11/2007</DueDate>

</Loan>

<Loan>

<LoanID>00003</LoanID>

<Item>An Interminable Journey</Item>

<LoanedTo>Joseph Jones</LoanedTo>

<DueDate>12/22/2007</DueDate>

</Loan>

</Loans>

Save the builder call when you are finished. Next, add a Simple Schema Generator buildercall to the model. This builder call is used to automatically generate a schema based on the Vari-able builder call, which is then used to define the structure of the result sets for the Service Oper-ation builder calls. Name the builder call loansSchema, and for the Sample Data input, select‘loans’ from the drop-down list. This is the variable you created earlier. Save the builder callwhen you are finished.

Adding an Action to Retrieve a List of Loans

Now, add an Action List builder call to the model. The Action List defines the action to be calledwhen the retrieveLoansList service operation is consumed, which you create in a later step. Namethe Action List getLoans and change the return type to IXml. IXml is a WPF interface used toaccess and manipulate XML. For more information on IXml, see Chapter 9, “Using Web Ser-vices and Manipulating XML.”

Open the Select Action dialog for the first row in the Actions input, which you do by click-ing on the ellipsis button on the first row of the Actions input. Select Special, Return, then selectthe loans Variable from under the Variables section and press OK. The action should appear in theAction List as follows:

Return!${Variables/loans/Loans}

When the Action List is called, this action returns the entire Loans variable created by theVariable builder. Save the builder call when you are finished.

Creating a Service Provider 169

Page 207: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Specifying the getLoansList Operation

Next, you create the first operation for the loansService service. This operation returns a list ofloans (by calling the getLoansList Action List). Add a Service Operation builder call to the modeland make sure the Service Operation Properties section is expanded. Select loansService for theData Service input, which links the operation to the loansService service created by the ServiceDefinition builder call.

The Operation Name input defines how the operation is referred to by consumers. Changethis input to getLoansList—there is no problem with this being the same name as your ActionList. The Action To Call input defines what happens when the operation is consumed. This inputshould be changed to point to your Action List (getLoansList). Note that the Operation Descrip-tion input is left blank, because it appears only to service consumers when the service provider isdefined as a Web service.

Make sure ‘No inputs’ is selected for the Input Structure Handling input in the OperationInputs section of the builder call. This specifies that the operation has no inputs—consumers haveonly to specify that they want to consume the operation to retrieve the loans list.

Expand the Operation Results section of the builder call and select Specify Result Schemafor the Result Structure Handling input. This enables you to manually specify the structure of theresults to be returned from the operation. For the Result Field Mapping input, select the topmostelement in the Loans schema (Loans). The Loans element contains a list of Loan elements and isreturned from the getLoansList Action List. The input should read loansSchema/Loans when youare finished. Make sure the Result Field Mapping input is set to Automatic, which automaticallymaps results from the called action to the result returned from the service operation.

Save the builder call when you are finished.

Adding a Method to Retrieve a Specific Loan

Add a Method builder call to the model and name it getLoanFromID. This method returns a par-ticular loan based on a loan ID argument and is called whenever the getLoanDetail operation isconsumed. A Method builder call is used, rather than an Action List, because some IXml manipu-lation is required to link loanIDs to loans.

Expand the Arguments section of the builder call and add a single argument called loanIDof type String. This argument corresponds to a particular loan, and you access it from the methoddefined in the Method Body Input.

Change the Return Type of the builder call to IXml, and then enter in the following codeinto the Method Body input:

{

//cycle through loans variable to get each loan

IXml loans = webAppAccess.getVariables().getXml(“loans”);

for (IXml loan = loans.getFirstChildElement(); loan !=null;

loan = loan.getNextSiblingElement())

{

170 Chapter 7 Communicating Between Portlets

Page 208: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

//look for match on loanID element

if ( loan.getText(“Loan/LoanID”).equals(loanID) )

//match found, return the current loan

return loan;

}

//no match found, return empty loan

return XmlUtil.create(“Loan”);

}

This code cycles through each of the loan elements in the loans list, and checks to seewhether the loan ID of the element matches the loan ID passed in to the method. For more infor-mation on the use of IXml, see Chapter 9. Save the builder call when you are finished.

Specifying the getLoanDetail Operation

The final builder call for the service provider is another Service Operation builder call. Thisbuilder call defines a second operation for the loansService service, which displays details for aparticular loan (by calling the getLoanFromID Method). Add a Service Operation builder call tothe model and point the Data Service input to loansService. Change the Operation Name togetLoanDetail, and the Action To Call to getLoanFromID. This creates a new operation onthe loansService service called getLoanDetail, which runs the getLoanFromID method whenconsumed.

In the Operation Inputs section of the builder call, select ‘Use structure from called action’for the Input Structure Handling input and make sure the Input Field Mapping input is set toAutomatic. This specifies that the inputs to the operation are defined by the getLoanFromIDMethod, and should be automatically mapped to the inputs in getLoanFromID.

Fill out the Operation Results section of the builder call the same as the Operation Resultssection in the previous Service Operation builder call, which specifies that the structure of theresults to be returned from the operation is defined by the Loan element in the Loans schema.Save the builder call when you are finished.

You have now finished building your service provider. The next section discusses how youcan test your service provider before moving on to create the list portlet and detail portlet.

Testing the Service Provider

Because you enabled test support for your service, WPF automatically generates test pages for yourservice provider, which you can disable from the Testing Support section of the Service Definitionbuilder call. This enables you to test the service provider directly from the IDE. To test the service,run the loansService model from the WPF Designer by clicking the icon on the toolbar. This

Testing the Service Provider 171

Page 209: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

runs the currently active model (for instance, loansService) with the last run configuration youused. If you have not set up a run configuration before, you are prompted to do so—create a newconfiguration under the WebSphere Portlet Factory Model category. If you want more informationon setting up a run configuration, see the “Testing the Application” section in Chapter 1.

After you run loansService, you should see the index test page in your default Webbrowser, as shown in Figure 7.1. This screen lists all the operations available on the loansServiceservice.

172 Chapter 7 Communicating Between Portlets

Figure 7.1 Index test page from the loansService model.

To test the getLoansList operation, click the getLoansList link. You should see a list ofloans, as shown in Figure 7.2. If not, check that you don’t have any errors showing in the Prob-lems view in the IDE and that you have completed all the steps in the previous section correctly.Press Back to return to the index page.

Figure 7.2 Testing the getLoansList operation.

To test the getLoanDetail operation, click the getLoanDetail link. The screen that followsasks you to enter in an ID of a loan you would like to retrieve details for. Enter in 00001 as the IDand press the Submit Query button. You should see some details for the loan that has an ID of00001 (that is, The Gullible Traveler), as shown in Figure 7.3. Press Back when you are finished.

Close the loansService model when you’ve finished testing it. You now have a service provider called loansService, which provides a list of loans and

details on individual loans. The next few sections walk through the process of creating consumersfor the loansService service in the form of a list portlet and detail portlet.

Page 210: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a List Portlet 173

Figure 7.3 Testing the getLoanDetail operation.

Creating a List Portlet

This section describes how to add another model to your project, which is surfaced to a portalserver as a portlet. The portlet consumes the service created in the previous section, and displaysa list of loans to the user. When a loan in the list is clicked, the ID of the loan is sent to the Web-Sphere Property Broker, which can then be read by other portlets. A screenshot of both the listand detail portlets is shown later in Figure 7.15.

The model uses the following builders to provide its functionality:

• Portlet Adapter

• Service Consumer

• View & Form

• Cooperative Portlet Source

Creating a Model

To build the list portlet, select File, New, WebSphere Portlet Factory Model from the File menu tobring up the WebSphere Portlet Factory Model dialog. On the next screen, select your WPF projectand press Next. The next screen lists different types of models WPF can create for you automati-cally. You can create service consumers in WPF in two ways: the first is to let WPF create one foryou, and the second is to create the service consumer manually. The builders you use to create thelist portlet in this section are fairly standard, so you can opt for WPF to create them for you. SelectList and Detail Service Consumer from the Service Consumers category and press Next.

Specifying the Service

The next screen asks you define a portlet name and service provider model for the consumer. Theportlet name is also used as a prefix when the wizard names some of the builder calls in yourmodel. Name the portlet loans and select chapter07/loansService as the service provider model.Click Next to continue.

Page 211: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Specifying List and Detail Operations

You now need to specify an operation to retrieve view data—the list portion of your portlet.Select getLoansList from the drop down and press the Next button to edit the detail portion of theportlet. Although the list portlet in this chapter is intended to be used as a list portlet only, defin-ing the detail portion gives the loansList model the flexibility to be run as a list and detail portlettogether if a separate detail portlet is unavailable. Fill out the settings on this screen, as shown inFigure 7.4. This converts the loanID column values into clickable links that run the getLoanDe-tail operation when clicked. Press Next when you are finished.

174 Chapter 7 Communicating Between Portlets

Figure 7.4 Configuring the detail portion of the loansList model.

Now, you need to define a uniquely identifying parameter that is used to open a loan whena loan ID is clicked. Enter in the loan ID from the loan on the currently selected row, as shown inFigure 7.5, and click the Next button.

Name the model loansList and make sure it is created in the directory models/chapter07,and then press Finish. This creates a new model called loansList in your WPF project, and opensthe model in the Model Editor and Outline view. The loansList model contains three builder calls:a Portlet Adapter, a Service Consumer, and a View & Form.

Page 212: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a List Portlet 175

Figure 7.5 Configuring input overrides for the loansList model.

Configuring the Portlet Adapter

The Portlet Adapter builder converts the model into a portlet, which can be viewed inside a portal.Note that if you make any changes to this builder call, including the changes you are about tomake, you need to rebuild the deployed application before you can see the results of the changes.For more information on this process, see the example in Chapter 1. The Service Consumerbuilder makes the operations in the loansService service available in the current model, and theView & Form builder displays the list and detail data in the model to the screen.

You need to make two small changes to the Portlet Adapter builder call. Double-click thePortlet Adapter builder call to open it in the Model Editor, and then change the Portlet Title toLoans List and the Portlet Description to List of loans. Save the builder call when you arefinished. The Portlet Title identifies the portlet inside the portal—it is actually displayed in thetitle bar of the portlet—and the Portlet Description appears on various administration screensinside the portal.

Defining the Portlet as a Cooperative Source

The final step in building the list portlet is to add a Cooperative Portlet Source builder call. Thisbuilder call defines the structure and content of the information to send to the Property Broker(for instance, the loan ID). A Cooperative Portlet Target builder call is then used in the detail port-let to receive the loan ID from the Property Broker.

Page 213: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Add a Cooperative Portlet Source builder call to the loansList model and then name itopenLoanDetail. Change the Type input to Property Broker Link, which replaces the links cre-ated by the View & Form builder with links that send the loan ID to the Property Broker. Note thatthe links are replaced only when the model is viewed as a portlet and the Property Broker is cor-rectly configured; otherwise, the links created by the View & Form builder call are retained.

TIP

The Type input gives you four options for specifying a communication method. The first two,C2A Single Action and C2A Multiple Action, define click-to-action tags that can be placedon the page. Click-to-action is a feature of the WebSphere Portlet API, which has beendeprecated in favor of the JSR-168 standard and is provided for backward compatibilityonly. The remaining two options define methods for publishing properties to the PropertyBroker. Whereas the Property Broker Link option automatically creates links on the page tocommunicate with the Property Broker, the Property Broker Action option creates an actionthat can be called from any control, such as a link, button, and so on. For more information,read the “Property Broker Action” section in this chapter.

In the Page location section of the Cooperative Portlet Source builder call, specify loans-View_ViewPage as the Page and LoanID as the tag. This replaces the ID links created by theView & Form builder call with new links that publish information to the Property Broker.

For portlets to communicate via the Property Broker, they need to use the same namespace.In the example in this chapter, the Cooperative Portlet Source and Cooperative Portlet Target bothneed to have the same namespace defined. Leave the default value for the Namespace input.

The Output Definitions section defines the information that you send to the PropertyBroker. Fill out this section, as shown in Figure 7.6. Note that the Value input should read${Variables/LoanLoopVar/Loan/LoanID}. This declares that whenever a loan ID link isclicked, the loan ID of the selected loan should be sent as a String called loanID to the PropertyBroker. Save the builder call when you are finished.

176 Chapter 7 Communicating Between Portlets

Figure 7.6 Configuring output definitions for the Cooperative Portlet Source builder call.

Your project now contains a list portlet. The next section describes how to test this portletfrom your IDE.

Page 214: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Detail Portlet 177

Testing the List Portlet

Although you cannot test the communicative capabilities of the list portlet at this stage, becausethere is no detail portlet to communicate with, you should run the loansList model from the IDEto see if you are getting any errors. To do this, run the loansList model from the WPF Designer.You should see a list of loans in your default Web browser, as shown in Figure 7.7.

Figure 7.7 List of loans from the loansList model.

Notice that the ID of each loan is a clickable link. If you click on the ID link for a particularloan, you should see some details for that loan. For example, clicking on the ID for A TravelingAunt should return the details shown in Figure 7.8.

Figure 7.8 Testing the getLoanDetail operation.

Note that currently the list portlet functions as both a list and detail portlet, because theView & Form builder call provides links that make it possible to open details on a loan from theloans list. However, when you deploy the loansList model as a portlet and configure the PropertyBroker, these links are replaced with links from the Cooperative Portlet Source builder call.When the links from the Cooperative Portlet Source builder call are used, the detail page in thelist portlet cannot open when a loan ID is clicked. Close the loansList model when you’ve fin-ished testing it.

You now have a list portlet that provides a list of loans by consuming the loansService ser-vice. The next section describes how to create a detail portlet that displays details for a loanclicked in the list portlet.

Creating a Detail Portlet

This section describes how to build a detail portlet, which communicates with the list portlet cre-ated earlier. As with the previous portlet, this portlet consumes the loansService service to obtainits loan information. Details for loans selected in the list portlet are brought up in the detail port-let via the Property Broker—a screen shot of the portlet is shown later in Figure 7.15.

Page 215: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The model uses the following builders to provide its functionality:

• Portlet Adapter

• Service Consumer

• Page (x2)

• Action List

• Data Page

• Cooperative Portlet Target

• Event Handler

Creating a Model

The list model is a good starting point for building the detail portlet, so make a new copy of thelist model by selecting the loansList model in the Project Explorer view, and then pressingCtrl+C, then Ctl+V. Name the new model loanDetail when prompted.

Double-click the loanDetail model to open it for editing. Before you add builder calls tocommunicate with the loansList portlet, you should first modify the loanDetail model so it doesnot conflict with the loansList model when it is deployed as a portlet.

To do this, open the Portlet Adapter builder call in the loanDetail model, change the Nameinput to loanDetail, and then change the Portlet Title input to Loan Detail. This ensures thatthere are no conflicts between the list and detail portlets when you deploy them. Also, change thePortlet Description to Loan details. Now delete the Cooperative Portlet Source builder callfrom the loanDetail model, because in the current example the loanDetail model is a target ofcommunication, not a source. Also, delete the View & Form builder because you are using a DataPage instead. You can reconfigure the View & Form so that it displays only detail information,but, in this case, it is easier to use a Data Page.

TIP

A single portlet can be both a target and a source of communication. For example, you mightwant a modification in the detail portlet (say, to the date of a particular loan) to be reflected inthe list portlet. In this case, both portlets are sources and are both are targets; an ID is sentfrom the list portlet to the detail portlet, and then a refresh request is sent back to the listportlet after the detail portlet is updated.

Note also that a single portlet can define multiple sources and multiple targets.You mightwant to define multiple sources for a portlet if the portlet publishes more than one piece ofinformation, and multiple targets are useful when you want to receive multiple propertiesfrom the Property Broker.

178 Chapter 7 Communicating Between Portlets

Page 216: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Default Message Page

Note that when the loanDetail portlet loads, it should not display any loan information, but rathera message indicating that no loan is currently selected. To bring this about, you need to addanother Page builder call to the model. Add a new Page builder call, and name the builder calldefaultPage. Enter in the following HTML into the Page Contents (HTML) input:

<html>

<body>

<div>

No loan selected.

</div>

</body>

</html>

This displays the text No loan selected. in the Loan Detail portlet. Save the builder callwhen you are finished.

TIP

You should use only the Page builder for small snippets of HTML specific to your applica-tion. Any HTML that you might want to share between projects should be included in anHTML file and then imported into your model using the Imported Page builder.

Adding a main Action

Now, add an Action List builder call to the model. Call the action list main, which causes theaction list to execute whenever the model is run. Enter defaultPage for the first action in theActions input and save the builder call. The loanDetail model now displays the defaultPagewhenever it runs.

Adding an Interface for Loan Details

Add another Page builder call to the model; this creates an HTML page that displays wheneverloan details are to be displayed for a loan. Change the Name of the builder call to detailsPage,and then enter in the following HTML into the Page Contents (HTML) input:

<html>

<body>

<span name=”loanDetails”></span>

</body>

</html>

Creating a Detail Portlet 179

Page 217: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page has a single span tag on it (loanDetails) that is overwritten with loan details usinga Data Page. Save the builder call when you are finished, and add a Data Page builder call to themodel to add the loan details. Type the name detailsPage for the Data Page, and then open theSelect Action dialog for the Variable input. Select the Loan element from the results of the get-LoanDetail operation, as shown in Figure 7.9, and press OK. This causes the Data Page to displaythe results of the getLoanDetail operation.

180 Chapter 7 Communicating Between Portlets

Figure 7.9 Selecting the Loan element.

Next, point the Page in Model input to detailsPage and change the Page Type to View Onlyso that there are no data entry controls inserted onto the page. Finally, specify detailsPage for theLocation for New Tags input and save the builder call.

Defining the Portlet as a Cooperative Target

The next step is to define the loanDetail model as a target for inter-portlet communication. To dothis, add a Cooperative Portlet Target builder call to the model. Change the Event Name input toopenLoanDetail, and then fill out the Input Definition section, as shown in Figure 7.10. Thesesettings define the communication inputs and should be the same as the outputs defined in theCooperative Portlet Source builder call in the loansList model. Keeping these settings identicalmakes it easier to understand what is being sent where, and prevents possible type mismatches.

Leave the Output Definition section blank. There are no outputs for this builder call,because nothing is sent back after the loanDetail portlet receives the loan ID.

Notice the namespace at the bottom of the builder call. This builder must be the same as thenamespace defined in the Cooperative Portlet Source builder call, or else the two portlets cannotcommunicate (you can leave the default value). Enter in Displays loan detail for the Cap-tion and save the builder call. Note that this caption describes what happens when the propertychanges, whereas the caption in the Input Definition section describes the property itself.

Page 218: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Detail Portlet 181

Figure 7.10 Configuring the Cooperative Portlet Target builder call.

Handling an Inter-Portlet Communication Event

You now have an event called openLoanDetail, which you later link to a loan ID being clicked inthe loansList model. However, you haven’t defined anything to happen when the openLoanDetailevent is triggered. To do this, you need an event handler. Add an Event Handler builder call to themodel and call it handleOpenLoanDetail. Select the openLoanDetail event from the EventName drop-down box and notice that a String argument called loanID has been added in theArguments section. This loanID is the same loanID as that specified in the Cooperative PortletTarget builder call, which means that you can now access the loan ID from the openLoanDetailevent.

Change the Return Type input to void, because there is no need to return any information tothe caller of this event. You simply want to perform some actions, which you specify in theActions input. Open the Select Action dialog for the first action and find the getLoanDetail oper-ation under the Methods section. Notice that there are two versions of the operation. Select theone that enables you to specify arguments, as shown in Figure 7.11, and press OK. A DefineMethod Call Arguments dialog appears; select the loan ID from under the Variables section in theSelect Action dialog, which should then populate the value ${Arguments/loanID} to the underly-ing dialog. Press OK when you are finished to accept the new action.

Figure 7.11 Adding the loansGetLoanDetailWithArgs method.

Page 219: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

182 Chapter 7 Communicating Between Portlets

For the second action, select the details page from under the Page section of the SelectAction dialog. It appears as ‘detailsPage’. The actions are now complete: The first action con-sumes the getLoanDetail operation on the loansService service, passing in the loan ID as aparameter. This loads only the information into a results variable, so the second action is neces-sary to display the results. Save the builder call when you are finished.

Your project now contains a detail portlet. You will run a preliminary test on the detail port-let in the next section, and then test it in full after it has been deployed to a portal server and theProperty Broker has been configured.

Testing the Detail Portlet

At this point, you should test that there are no obvious problems in the loanDetail model by pre-viewing it from your IDE. You should see the message shown in Figure 7.12 displayed on thescreen.

Figure 7.12 Testing the loanDetail model.

After you have configured the Property Broker later in this chapter, you can do a full test ofthe communication between the list and detail portlets. Before you do this, however, you shouldrebuild your application on the portal server. For instructions on how to do this, see the examplein Chapter 1. Then, you can view the list and detail models as portlets. After you have added theportlets to a page in the portal, they should appear, as shown in Figure 7.13.

Figure 7.13 The loans application portlets.

Your application has now been successfully deployed to the portal server, although theportlets contained in the application cannot communicate with each other yet. The next sectiondiscusses how to set up this communication using the WebSphere Property Broker.

Page 220: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Configuring the WebSphere Property Broker 183

Configuring the WebSphere Property Broker

When setting up inter-portlet communication via the WebSphere Property Broker, some configu-ration is required to link or wire portlets together after they have been deployed. This sectionwalks through the process of configuring the list portlet to send a loan ID to the detail portlet,which then displays details for the selected loan. At this point, note that the portlets are not wiredtogether, so if you click on a loan in the list portlet, the details are opened within the same portlet,and the detail portlet still displays the No loan selected. message.

To configure the Property Broker, first log in to the portal as a user who has access to wireportlets together. You need a user with Privileged User access or higher to the portal page that isto contain the loan portlets. Navigate to where you added the Loan Detail and Loans List portletsand open the Page Menu for the page. You can do this in WebSphere Portal 6, for example, bymoving the cursor to the right of the page title until a small arrow icon is revealed, as shown inFigure 7.14. Click the arrow to open the Page Menu, and then select Edit Page Layout.

Figure 7.14 Opening the Page menu.

Click on the Wires tab, which should be the last tab on the Page Layout page. If you can’tsee the Wires tab, check that you are logged in as a user with at least privileged user access to thecurrent page. This page lets you define inter-portlet communication for the portal. You can evendefine communication from one page to another. Note that you only define communication forportlets that have been added to a page in the portal. In this step, you add a row to the Wires pageto define the communication between the list and detail portlet.

Select Loans List from the Source portlet dropdown, and then select loanID in the Sendingdropdown. These values are taken from the Cooperative Portlet Source builder call, although theycan be defined using IDEs other than WPF (WPF applications can communicate with non-WPFapplications, and vice-versa). The current page is automatically selected as the target page. SelectLoan Detail for the Target portlet, and set the Receiving dropdown to ‘Displays loan detail,loanID’. This is the action caption and input name defined in the Cooperative Portlet Targetbuilder call.

The final drop-down box gives you a choice of creating the wire as personal or public. Apersonal wire is accessible only by the current user, whereas a public wire is accessible to allusers. Leave the default setting and press the icon to add the wire to the portal. Wait for thepage to reload and press the Done button to return to the portal.

You have now configured communication between the list and detail portlet.

Page 221: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing Inter-Portlet Communication

When you press the Done button on the Wires page, you are returned to where the list and detailportlets are displayed on the portal. To test that the communication is working correctly, click ona loan in the Loans List portlet. When the page reloads, a loan should be opened in the LoanDetail portlet, and the Loans List portlet should still display the loans list, rather than the loandetail, as it did previously. For example, clicking on 00003 should bring up loan details for TheInterminable Journey, as shown in Figure 7.15.

184 Chapter 7 Communicating Between Portlets

Figure 7.15 Testing inter-portlet communication in the portal.

You have now successfully created, deployed, and tested an application consisting of inter-communicating portlets. However, the method employed in this section is only one of severalways to set up inter-portlet communication. Some alternatives to this approach are discussed inthe next section.

Alternative Communication Methods

Although the WebSphere Property Broker is a highly flexible and versatile method of inter-portlet communication, there are some situations where other approaches might provide morevalue. For example, the Property Broker is available only in WebSphere Portal, so if you transferyour portlets to another type of portal server, you need to modify the communication techniqueused. Second, communicating via the Property Broker requires that a wire must be set upbetween two portlets before they can communicate; this creates extra configuration steps andleaves more of the configuration process open to human error—although, it can also be regardedas a good thing, because it gives end users more control over the communication process.

There are several alternative options available for setting up inter-portlet communication inWPF, and each has its own strengths and weaknesses. These methods are described next.

Page 222: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Property Broker Action

Property Broker Actions, as opposed to Property Broker Links, let you define your communica-tion as actions rather than as clickable links. The advantage of this approach is that you have morecontrol over how the action is run—whether it be programmatically or from a UI control; how-ever, the disadvantage is that more WPF configuration is required than when using PropertyBroker Links. The communication on the Property Broker is no different—that is, you still pub-lish properties in the same way.

Property Broker Actions are not really an alternative method of communication to PropertyBroker Links, because they are really just Property Broker Links that don’t produce a link in theUI. However, Property Broker Actions can be quite useful, and because the configuration processis sufficiently different, an example is included.

The following builder is added to the loansList model in this section:• Link

Modifying the Cooperative Source

To alter the communication in the loans application to use Property Broker Actions, first open theCooperative Portlet Source builder call in the loansList model. Change the Type input from Prop-erty Broker Link to Property Broker Action. This creates an action to publish the loan ID to theProperty Broker, but it does not create the corresponding trigger for the action, such as a link.Save the builder call when you are finished.

Adding a Link and Configuring Communication

To trigger the Property Broker Action, add a Link builder call to the loansList model. Name theLink loanIDLink. In the Page Location section of the builder call, fill out the Page input asloansView_ViewPage and the Tag input as LoanID. This replaces the loan ID links created bythe View & Form builder call with the new links defined by the Link builder.

Select pbAction_openLoanDetail for the Action input, which triggers the Property BrokerAction when a loan ID is clicked. Notice that two arguments with the pbAction_openLoanDetail_Arg prefix are automatically added to the Input Mappings input in the Arguments sectionof the builder call. You need to replace the values of these arguments. The first argument to anyProperty Broker Action must be the name of the action (that is, pbAction_openLoanDetail). Thisargument is used by the portal to associate the Property Broker call with a particular PropertyBroker action. The argument is added automatically when using Property Broker Links, butneeds to be added manually when using Property Broker Actions. Rename the argument toACTION_NAME, and then type the name of the action (pbAction_openLoanDetail) as thevalue. Note that the name and value of the argument must be written as specified, or the inter-portlet communication cannot work. Note that the Evaluate Arguments input must be set to ‘Asthe page is rendered’; if it is not, the links cannot be generated correctly.

Because the Cooperative Portlet Source builder call is expecting an argument, you mustalso change the second argument for each link created by the Link builder call. To do this, change

Alternative Communication Methods 185

Page 223: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

the second argument to point to the currently selected loan, and change the name of the argumentto loanID so that it is easier to identify, as shown in Figure 7.16. Note that the value of the argu-ment is the same as the value of the argument specified in the Cooperative Portlet Source buildercall. In the next step, you remove the value from the Cooperative Portlet Source builder call sothat the value from the Link builder call is used instead. Save the builder call when you arefinished.

186 Chapter 7 Communicating Between Portlets

Figure 7.16 Adding an argument to the Link builder call.

Open the Cooperative Portlet Source builder call and delete the Value input for the loanIDoutput. The value for the loanID output is now taken from the Link builder call.

You have now finished configuring the loansList model. No changes are required to theloanDetail model, because the parameter published to the Property Broker is the same as it wasbefore. Note that the ACTION_NAME parameter does not need to be specified in the Coopera-tive Portlet Source builder call. Rebuild your portlet application by right-clicking on your projectand selecting Portal Server WAR, Build Portlet War. You don’t need to reset or modify the wire,because the structure of the communication hasn’t changed. The only thing that has changed ishow you actually trigger the event to send to the Property Broker. To test the new communicationmethod, navigate to the loans portlets in the portal and click on a loan in the Loans List portlet.The corresponding loan should open in the Loan Detail portlet.

You have now successfully configured the loans application to use Property Broker Actionsrather than Property Broker Links. Again, note that this change doesn’t change the type of com-munication, but merely how you use it in WPF.

WPF Event Model

When using the WPF event model, communication between portlets occurs by triggering andhandling an event. This approach is easy to use and configure: First, you declare an event in asource and target portlet, and then you trigger, or fire, the event in the source portlet. Finally, youhandle the event in the target portlet. Events can be fired and targeted to a particular portlet,

Page 224: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Alternative Communication Methods 187

or they can be fired in such a way that they can be accessed by any other portlet in the sameWAR file.

You can trigger events using the WPF event model in two ways: on the server and on theclient. Both methods enable you to access and manipulate resources on the server, such as read-ing and updating data from a service provider, but triggering events on the client also enables youto perform partial page refreshes. Partial page refreshes improve the speed of your application,and users appreciate that they can interact with your portlet without having to constantly reloadthe entire portal page. Partial page refreshes are covered in more detail in Chapter 13, “UsingAjax and Dojo.” Note that you can only pass parameters to events when using server-side events,which is why both types of events are sometimes used together; for example, you might use aserver-side event to update data in a Lotus Notes database, and then use a client-side event to par-tially refresh the page with this data. The example at the end of this section uses only a server-sideevent.

Be aware that when using the WPF event model approach, all inter-communicating portletsneed to be contained in the same WAR file, which also means that they all need to be built withWPF. As a result, the WPF event model is most useful for setting up inter-portlet communicationwhen interoperability with other applications is not a concern.

The following builders are added in this section:• Event Declaration (x2)

Defining an Event

To alter the communication in the loans application to use the WPF event model, the first step isto define an event, which is triggered every time a user clicks on a loan ID. Add an Event Decla-ration builder call and change the Event Name input to openLoanDetail. Add an argumentcalled loanId of type String to the Arguments section so that any triggers for the event need topass in a String value when they trigger the event. This String corresponds to the loan ID of theloan that the user clicks on. The event is triggered any time details for a loan are opened. Save thebuilder call when you are finished.

Triggering the Event

Now that you have finished configuring the event declaration, you should modify the loansListmodel to trigger the event. Open the Link builder call in the loansList model and change theAction input to fireopenLoanDetail. You can select this from the Select Action dialog. If the fire-openLoanDetail action does not appear, make sure you have saved your Event Declaration. ThefireopenLoanDetail action fires the openLoanDetail event instead of publishing the loan ID to theProperty Broker.

Page 225: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

If you want to fire an event to a specific target, you can use the fireTargeted trigger. Forexample, to fire an event to the loanDetail model so that it can’t be accessed by other mod-els, select fireTargetedopenLoanDetail instead of fireopenLoanDetail.You are prompted forthe target of the event, and you can specify four possible targets:

${Java/WebAppAccess.EVENT_TARGET_ALL})

This fires the event to all models in the current application.

${Java/WebAppAccess.EVENT_TARGET_PARENT})

This fires the event to the parent model of the current model, which is any model that isused to load the current model (for example, if you’re using a Linked Model builder call).

${Java/WebAppAccess.EVENT_TARGET_SELF})

This targets the event to the current model.

${Java/WebAppAccess.getModelInstance(targetModel)})

This targets the event to the targetModel model. You should substitute the text target-Model with the actual name of the target model—for example, loanDetail.

Notice that an argument called fireopenLoanDetail_Arg1 has been added underneath theArguments section of the builder call. This argument has been created by WPF to cater for theloan ID that is supposed to be passed to the event, but you still have two arguments left over fromwhen you configured the Property Broker Action. The loanID argument left over from the Prop-erty Broker Action is the argument you want to pass to the event when it is fired, so remove theother two arguments from the Input Mappings input. The Arguments section should now appear,as shown in Figure 7.17.

188 Chapter 7 Communicating Between Portlets

Figure 7.17 Setting arguments for the Link builder call.

You have now finished configuring the Link builder call. Disable the Cooperative PortletSource builder call as it is not being used, but you might want to use it again later. You can disablebuilder calls by right-clicking on them and selecting Disable. Save the model when you arefinished.

Page 226: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Alternative Communication Methods 189

Handling the Event

Now, you need to configure the loanDetail model to handle the openLoanDetail event. To do this,first open the loanDetail model and disable the Cooperative Portlet Target builder call, becauseyou are no longer using the Property Broker (don’t save the model yet). Copy the Event Declara-tion builder call from the loansList and paste it into the loanDetail model. This is done so thatboth models are using the same event. Because the event name in your Event Declaration is thesame as the event name in your Cooperative Portlet Target builder call, no changes are required tothe Event Handler builder call; it processes the openLoanDetail event as it is defined by the EventDeclaration now that the Cooperative Portlet Target is disabled.

Save the model to complete the configuration of your application to use inter-portlet com-munication via events. To test the new communication method, rebuild your application andnavigate to the loans portlets in the portal. Click on a loan in the Loans List portlet, and the corre-sponding loan should open in the Loan Detail portlet.

Shared Variables

Shared variables are perhaps the quickest and easiest way to implement inter-portlet communica-tion. Shared variables can be stored in one of four ways: in the HTTP session, in the HTTPrequest, in the JVM where the current WebApp is running, or using a custom Java class. Variablesstored in the JVM are accessed as static variables (the same copy is used across all instances ofthe portlet). To create or read a shared variable from a model, add a Shared Variable builder anddesignate a variable to share.

Note that variables stored in the HTTP session increase the amount of memory consumedby the session, and variables stored in the HTTP request have limited scope. Also, variables in theJVM cannot be accessed outside the JVM (for instance, across a cluster), and custom variablestorage methods require additional Java development. Provided you keep these concerns in mind,however, shared variables are a powerful and easy-to-configure method of inter-portlet communi-cation.

In the previous section, it was necessary to pass the loanID from the event trigger to theevent handler via an argument to the event. In this section, you use a shared variable in place ofthe loanID argument so that when you change the loanID variable in the loansList portlet, it isread in the loanDetail portlet and used to update the loan information. Note that in this example,an event is still used to access loan details for the loan ID stored in the shared variable. This isbecause even though the loan ID is shared between both models, the details portlet won’t knowthat it is supposed to refresh the other loan details unless an event is fired that causes this to hap-pen. Because changes to a shared variable do not in themselves trigger any events, shared vari-ables are often used in conjunction with the WPF event model.

The following builders are added in this section:

• Variable (x2)

• Shared Variable (x2)

• Action List

Page 227: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Removing the Event Argument

To alter the communication in the loans application to use the shared variable approach, firstremove the argument from the Event Declaration builder call in both the loansList and loanDetailmodels, because you are now storing the loan ID in a shared variable. The argument is listed inthe Arguments input of the Event Declaration. Save both instances of the builder call when youhave removed the arguments.

Adding a loanID Variable

Next, add a Variable builder call to the loansList model and call it loanID. Change the Type inputto String and save the builder call. This builder call holds the value of the currently selected loanID and is used in both models, so copy and paste the builder call into the loanDetail model. Savethe model when you are finished.

By default, each model uses its own instance of the variable created by the Variable buildercall. To share the variable, you need to add a Shared Variable builder call to each model. Add aShared Variable builder call to the loansList model first, and then name the builder call loanID-Shared. Change the Variable input to loanID.

The Scope input enables you to specify where the shared variable will be stored. As dis-cussed earlier, you have four options when setting a shared variables scope: Session, Request,Application, and Custom. Make sure this input is set to Session, which means that the variablevalue persists even when other links on the page are clicked. Then, change the Unique ID input toloanID and save the builder call. Make a copy of the Shared Variable builder call and paste it intothe loanDetail model. Save the model when you are finished.

Creating these Shared Builders shares the loanID variable in the HTTP session using thetext loanID as an identifier. The identifier can then be used from other processes and portlets toaccess the shared variable from the HTTP session. When referring to the variable from WPF,however, you need only to reference the name in the Variable builder call.

TIP

When referring to a shared variable in other builders, refer to the Variable builder call ratherthan the Shared Variable builder call.

Configuring Actions for loansList

The next step is to set up two actions in the loansList model. The first action changes the value ofthe loanID variable when a loan ID is clicked, and the second action fires the new openLoanDe-tail event without any arguments.

To add these actions, add an Action List builder call to the loansList model and call itselectLoan. Enter in an argument called loanID of type String in the Arguments input, andthen change the Return Type input to void to prevent the Action List from returning a value.

190 Chapter 7 Communicating Between Portlets

Page 228: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

For the first action, select Assignment from under the Special heading in the Select Actiondialog. For the Target variable, select the loan ID variable (Variables/loanID), and for the Sourcevariable, select the loanID argument from the Action List (${Arguments/loanID}). The MakeAssignment dialog should appear, as shown in Figure 7.18. Press OK when you are finished toaccept the action.

Alternative Communication Methods 191

Figure 7.18 Configuring the Make Assignment dialog.

For the second action, fire the openLoanDetail event by selecting fireopenLoanDetail fromthe Select Action dialog. Save the builder call when you’ve finished adding both actions.

Running selectLoan

Open the Link builder call and change the Action input to selectLoan. This runs the selectLoanaction list whenever a loan ID is clicked. WPF assumes that you want to set a new argument forthe selectLoan action list, so it automatically adds an extra argument to the Input Mappings input.You can delete the extra argument, because the previous loanID argument will suffice. Save themodel when you are finished.

Using the Shared Variable in the loanDetail Model

You need to configure the loanDetail model to use the shared variable instead of the argument inthe old openLoanDetail event. To do this, open the handleOpenLoanDetail Event Handler buildercall and change the first action in the Actions input to use the loanID variable instead of theloanID argument, which no longer exists. The new action should read loansGetLoanDetailWith-Args(${Variables/loanID}).

Save the builder call when you are finished. To test the new communication method,rebuild the application and navigate to the loans portlets in the portal, and then click on a loan inthe Loans List portlet. The corresponding loan should open in the Loan Detail portlet.

You have now successfully configured the loans application to use shared variables for itsinter-portlet communication.

Click-to-Action (C2A)

Click-to-action (C2A) facilitates inter-portlet communication through the use of portlet menusthat the user can configure. The C2A builders have been deprecated as of WPF 6.0, because they

Page 229: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

rely on the now deprecated WebSphere Portlet API, rather than the JSR-168 standard, so youshould avoid using C2A as your inter-portlet communication mechanism.

When to Use Inter-Portlet Communication

When developing portlets, in WPF or otherwise, spreading an application’s functionality acrossseveral inter-communicating portlets can help to provide a more customizable interface and ulti-mately produce more extensible applications. However, some scenarios are more conducive tointer-portlet communication than others. For example, you might not want to separate the list anddetail portions of a data access function if they are going to be used on a page that already con-tains a list and detail portlet, because multiple list and detail portlets on the same page can clutterand complicate the interface. Similarly, if a list portlet depends on another portlet on the page forits information, you might want to include the list as a second page in that portlet, rather than as aseparate portlet. The decision as to whether to combine functions into a single portlet is alsoinfluenced by how many other portlets you expect will be used on the same page and how muchspace they will take up. If you expect screen real estate to be scarce, perhaps you need to cater to800x600 resolutions, and if you expect multiple portlets to be used at once, it might be best toeconomize and combine several functions into a single portlet wherever possible, rather thanimplement the same functions using inter-portlet communication.

Having said this, inter-portlet communication is a powerful tool for portlet developers toimprove the usability of their applications and should be used wherever possible. As a generalrule, potentially reusable, high-level functions, such as the list and detail components of a dataportlet, are the best candidates for inter-communicating portlets, because they can be easilyincorporated into other applications. The information sent between each portlet is fairly simple—usually just a uniquely identifying key for a particular record or document—which reduces theinformation sent between the server and the client, and therefore also speeds up your application.It is also the sort of information that could be meaningful to other functions or processes. Click-ing on an item in a list portlet, for example, could trigger other portlets on the page to open charts,reports, or edit forms for that item.

Summary

In this chapter, you learned about the different approaches to implementing inter-portlet commu-nication in WPF, in addition to the strengths and weaknesses of each approach. You also created alibrary loan system that consisted of a service provider and two portlets, which demonstratedeach approach. When you clicked on a loan in the list portlet, it caused details on that loan to beopened in the detail portlet. Both portlets retrieved their data from the service provider.

The next chapter, “Using Java in Portlets,” discusses how to utilize Java code in your WPFapplications.

192 Chapter 7 Communicating Between Portlets

Page 230: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Important Points

• WPF portlets can communicate with each other using the WebSphere Property Broker,shared variables, or the WPF event model. Each approach has its own strengths andweaknesses.

• Communication via the WebSphere Property Broker is facilitated by publishing proper-ties to a WebSphere Portal Server mechanism known as the Property Broker, which thenroutes these properties off to other portlets. Implementing communication using theProperty Broker offers considerable flexibility, because it means that your portlets cancommunicate with portlets in other WARs, or even portlets built using environmentsother than WPF. Also, because WPF provides builders to automate the communicationconfiguration, you don’t need to write any code to implement the communication. How-ever, configuration in the portal is required before this mode of communication willwork.

• Shared variables can be configured to use a number of different stores and are perhapsthe quickest and easiest way to implement inter-portlet communication in WPF. How-ever, unless your portlets are all in the same WAR file, you need to write code to retrievethe variable values. This approach is best suited to storing one or two small pieces ofinformation used across an entire WPF application.

• The WPF event model also offers a quick and easy approach to inter-portlet communi-cation, and gives you the added benefit of a prepackaged WPF builder to handle commu-nication events without regenerating the entire portal page. This approach has limitedextensibility because all communicating portlets need to be contained in the same WARfile to be used effectively, and they need to be developed in WPF; however, it is wellsuited to WPF applications where events in one portlet trigger events in another.

Important Points 193

Page 231: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 232: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

195

C H A P T E R 8

Using Java in Portlets

Although WebSphere Portlet Factory (WPF) automates much of the Java development requiredto build portlet applications, you can certainly fine-tune and extend your WPF applications with alittle well-placed Java code. This chapter explains how you can work Java into your portlet appli-cations and walks through the creation of a simple portlet demonstrating some common uses forJava. By the end of this chapter, you will have a good understanding of the different approachesavailable for extending your applications with Java, as well as knowledge of the benefits anddrawbacks of each approach.

The example application discussed in this chapter utilizes one model and several Javasource files, which are available for download from ibmpressbooks.com/title/9780137134465,under the Chapter 8 folder. (Instructions for copying these files into your project are included in areadme.txt file in the same folder.) However, to increase your understanding of the topics dis-cussed in this chapter, it is recommended that you create the files yourself by following theexample.

The following topics are covered in this chapter:

• Java development considerations

• Java methods

• Java Application Programming Interfaces

• Java beans

• Creating a Java bean and bean manager

• Creating a service provider

• Creating a shopping cart portlet

• Java archives

Page 233: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Java Development Considerations

If you look under the covers of a WPF application, you can see that Java is used extensively toimplement each builder call; indeed, the Web application executed on the portal server is itself aJava application. You can view the Java code created by WPF from the WPF Designer by openingthe WebApp Tree tab for a particular model and viewing the contents of the Method and LinkedJava Object headings (see Figure 8.1). You cannot edit this Java from the WebApp Tree tab, butyou can influence how it is created (or overwrite it entirely) by modifying the inputs in buildercalls or by adding your own Java methods to the model.

196 Chapter 8 Using Java in Portlets

Figure 8.1 Viewing a model’s Java methods.

There is nothing wrong with developers using Java in their WPF applications per se; Javaundoubtedly improves your applications in certain scenarios, and in others, it is indispensable(such as in the implementation of complicated business logic). In most cases, however, the WPFbuilders are preferred to Java code as they are less error prone and easier to maintain. It also usu-ally takes much longer to write a Java class than it does to implement the same functionality usingbuilders.

Page 234: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

If you have sections of Java code that are frequently used across more than one applica-tion, you can include them inside a custom builder in WPF. This makes it easier for non-Java developers to interact with the code, helps enforce development standards, andreduces human error. Custom builders are discussed in Chapter 15, “Performance andProcess Optimization.”

Although it is important to keep the use of Java to a minimum, you should pay particularattention to minimizing the amount of Java used in presentation-level components (that is, thosethat are directly related to the look and feel of your portlet). A common problem in ordinary JSPdevelopment, for example, is the inclusion of inline Java scripts on the page. This increases thecomplexity of the page and also increases the skills required to understand it. Unless your Javacode is performing some very basic calculation directly relevant to the presentation of data, youshould abstract your Java code out into separate classes, and then surface them to your presenta-tion components via a service provider.

Java can be particularly helpful in several areas of development, however:

• Processing and business logic—Although the Action List builder can be used to defineprogram execution steps (and can also implement basic conditional statements), Javawill give you much more control over how the logic in your application is handled. Youcannot, for example, implement do…while or for…next loops using only the defaultWPF builders. You can, however, use conditional statements. See the Conditional State-ments in Action Lists sidebar for instructions on how to do this. For anything but themost basic program logic, then, it is likely that you will need to use Java to implement atleast some of the logic in your application.

• Action Lists can become difficult to read and understand if you are using largenumbers of actions—In these cases, it is often preferable to use Java code.

CONDITIONAL STATEMENTS IN ACTION LISTS

To insert a conditional statement into an Action List builder, bring up the Select Action dialog(by clicking the ellipsis button next to one of the actions in the Actions input) and navigate tothe Special, Conditional category. The if, else, and endif statements you find there can beused to create conditional statements. Conditional statements in WPF must take the followingform (note that you can also nest conditional statements inside other conditional statements):

IF ([condition]) THEN

[run action]

!ELSE

[run alternative action]

!ENDIF

Java Development Considerations 197

Page 235: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Note that conditional statements can make your Action Lists difficult to read, so if you findthat you are making extensive use of these statements (particularly if you are nesting condi-tional statements inside other conditional statements), you should consider using a Javamethod instead.

• Manipulating XML documents—Again, a number of builders in WPF can manipulateXML (the Transform family of builders, for example), but the Java IXml interface pro-vides you with a greater degree of control. An example of manipulating XML using theIXml interface is given in Chapter 9, “Using Web Services and Manipulating XML.”

• Interfacing with other Java frameworks—If your application needs to interact withother Java classes (say, for example, to process security information for the currentuser), you might need to write some Java methods to encapsulate this behavior. This isparticularly true when using frameworks that make heavy use of Java beans; however,be aware that you can surface functionality from Java beans using builders as well. Anexample using the default WPF builders is given later in this chapter.

The rest of this chapter explains some of the different methods available for adding Javacode to WPF applications. At the end of the chapter, a simple test application is created to demon-strate these techniques.

JavaMethods

You can insert Java methods into WPF applications in a number of ways. This section describesthe relative benefits and drawbacks of each approach. Note that Java methods can also be encap-sulated in JARs and Java beans, which are discussed in separate sections later in the chapter.

Inline Java

Java statements can be used to evaluate and return expression results for builder inputs that acceptindirect references. Indirect references are where the input contains a reference to another vari-able or function that provides the input’s value, such as the Actions input in the Action Listbuilder, or the Text input in the Text Input builder. For example, when you specify a parameter foran action in an Action List builder, an additional Java category will show up in the Choose Refer-ence dialog (see Figure 8.2). The values under this category will give you access to particularJava objects, with the exception of the <replace with Java expression> category, which you canuse to insert the results of a Java expression into the action list. All inline Java statements are inthe form ${Java/[Java expression]}. For example, the expression:

${Java/webAppAccess.getModelName()}

could be used to return the name of the current model. (The webAppAccess object is a memoryresident object you can use to access aspects of the WebApp and is discussed in the “Java Appli-cation Programming Interfaces” section later in this chapter.)

198 Chapter 8 Using Java in Portlets

Page 236: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

JavaMethods 199

Figure 8.2 The Java category.

WARNING

Each inline Java statement should be a single Java expression; you cannot separate partsof an inline Java statement using semi-colons. Note that you do not have to close off aninline Java statement with a semi-colon. Also, do not use curly braces ({ and }) inside aninline Java statement, as they are used to delineate the boundaries of the entire statement.

Inline Java should be used with caution because it can make action lists difficult to read andmaintain. However, it can be useful for debugging, especially when used in conjunction with theSystemOut action from the Select Action dialog. The following line, for example, could be usedto write the name of the current model to the console:

SystemOut!${Java/webAppAccess.getModelName()}

Page 237: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

The Special, Java category in the Choose Reference dialog enables you to access severalcommonly used Java objects. Of particular use in this category is the UserID object, whichreturns the name of the current user, and the RequestInputs object, which returns a stringcontaining all of the values the user has entered onto the form. The HttpServletRequestand HttpServletResponse options can be used to gain access to the javax.servlet.http.HttpServletRequest and javax.servlet.http.HttpServletResponse objects. The use of theseobjects is discussed in the “Java Application Programming Interfaces” section later in thischapter.

Action Lists

The Action List builder in WPF enables you to run Java commands and methods in the same waythat you can from many of the builder inputs in WPF, only it also enables you to include morethan one of these actions in a sequence. As a result, Action Lists are very useful for organizingexecution flow in your application. For example, an Action List might be used to set the value ofa variable, then call a Java Method (passing in the variable as a parameter), and then display aresults page. Action Lists also enable you to use limited conditional statements (as discussed inthe “Conditional Statements in Action Lists” sidebar earlier in this chapter). Although you will nodoubt need to make extensive use of Action Lists in your WPF applications, you should try tokeep them fairly simple (that is, using as few actions as possible) to maintain their readability. Ifyou find that your Action Lists have so many actions that they are difficult to understand, youshould look at the Method builder and Linked Java Object (LJO) builders as possible alternatives(both of these approaches are discussed in the following sections).

TheMethod Builder

If your Java methods are a bit more involved than a single expression, you might want to use theMethod builder to contain your Java code. The Method builder enables you to encapsulate a Javamethod within a single set of curly braces (you cannot define multiple methods, or any classes, ina Method builder). You can then call this Java method from other builders or Java methods. Youcan also specify a list of arguments, a return type, and a list of imports for the method (note thatyou do not need to import any of the WPF classes or any of the Java core classes). You can see alist of all the methods in the current WebApp by opening a model, selecting the WebApp Tree tab,and navigating to the WebApp, Methods section.

The Method builder can also be used for overwriting functionality created by other WPFbuilders. Although overwriting builder functionality is error prone and should be used with cau-tion, it also gives you that extra degree of control when you find that simply modifying the resultsof a builder is not sufficient. For example, you might look on the WebApp Tree tab and notice thatWPF has created a method for you called page1_SaveData, which handles the save process forpage1. This method might provide some functionality that you don’t want, or that you want to

200 Chapter 8 Using Java in Portlets

Page 238: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

modify in some way. To modify the method, then, you can give your Method builder the samename as the method listed in the WebApp Tree, and then enable the Rename Existing Input box.Copy and paste the method from the WebApp Tree into your own method, and then change thecode to your liking.

You do need to be aware of a number of caveats when using the Method builder. The first isthat the Method builder does not have all of the features of the standard Java editor used inEclipse. Also, Java Methods are harder to share between developers when they are contained inMethod builders. These factors combine to make maintenance of Method builders more difficultthan maintaining traditional Java files; as a result, the Method builder should only be used forsimple methods that won’t be shared between models or projects. A good implementation of theMethod builder, for example, would be encapsulating logic for other Java calls. Also, due to itsconvenience, the Method builder is well suited to quick and simple Java methods. You should,however, minimize the amount of Method builders used in an application, and if you intend todistribute your code between models or projects (or your methods are quite long), you shouldconsider using a Linked Java Object builder instead (LJOs are discussed in the next section).

WARNING

If you receive the message “sun.tools.javac.Main has been deprecated” when executing aJava method, the Java Virtual Machine (JVM) has been unable to run your Java code.Check the error message carefully for more precise details and make sure no errors arelisted in the Problems view in the WPF Designer.

The numerous Java snippets included in the “Java Application Programming Interfaces”section of this chapter are ideal candidates for Method builder code. The example included in the“Java Beans” section of this chapter also demonstrates how you can use the Method builder tointeract with an LJO and return a Java object to another builder call.

The Linked Java Object Builder

The final option available for inserting Java methods into a WPF application is the Linked JavaObject (LJO) builder. An LJO links to an actual Java .class file in your project, and makes itsmethods available to other builders and Java methods in the model. You can see a list of all theLJOs in your project by opening a model, selecting the WebApp Tree tab, and navigating to theWebApp, Linked Java Objects section. LJOs have several advantages over the Method builderand inline Java code:

• They are easier to share between developers.

• They enable you to take advantage of all the Eclipse Java Editor features and shortcuts.

• You can make use of pre-existing Java files.

JavaMethods 201

Page 239: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

One disadvantage of using an LJO is that you need to manually write code to import Javalibraries and define classes (tasks that you don’t have to perform when using the Method builder).However, these tasks are relatively straightforward and shouldn’t pose any problems for thosewho have any familiarity with Java.

You can use two locations when inserting Java files into your project. If you have (or wantto create) .java files that you plan on editing, insert the files into the source folder in your project.By default, the source folder is the WebContent/WEB-INF/work/source directory of your project.A link to this folder is also available under the root folder of your project in the Project Explorerview. Whenever you save a Java file in this directory, the Java compiler creates (or updates if italready exists) a binary version of the file (located in the WebContent/WEB-INF/work/classesdirectory by default) that can then be linked to from an LJO or executed from other Java code. If,however, you don’t want to modify the source code and just want to use a precompiled version ofa Java class, you can insert it into the WebContent/WEB-INF/classes directory or WebContent/WEB-INF/lib directory. Files stored in these directories are not automatically updated when yousave source files elsewhere in the project.

TIP

The dynamic loading of class files is indispensable in development and is enabled bydefault in WPF. Only classes in the WebContent/WEB-INF/work/classes directory areloaded dynamically.

The example at the end of the “Java Beans” section of this chapter demonstrates how youcan use an LJO to create a factory class, which you use to access and manipulate customer infor-mation stored in a Java bean.

Java Application Programming Interfaces

When writing Java methods in WPF, you can use a number of Application Programming Inter-faces (APIs) that interact with WPF artifacts. Some of the more useful APIs used in WPF arelisted in this section.

TIP

You can bring up the Javadoc for WPF APIs by navigating to the IBM WebSphere PortletFactory Designer, Reference, API documentation section in the WPF Designer help.

When using Java APIs in the WPF Designer, you need to make sure the Java compilerknows where to find all of the relevant API classes. Classes in the WPF foundation libraries (suchas WebApp and IXml) are automatically found, as are all of the basic classes in the Java runtime

202 Chapter 8 Using Java in Portlets

Page 240: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

library (such as System). However, other classes need to be qualified (you can see which classesare automatically imported by scrolling to the top of the WebApp, Methods section in theWebApp Tree tab of the Model Editor). To qualify classes when using the Method builder, youcan either type the fully qualified name of the class every time you use it (for instance,javax.naming.Context), or you can type just the class name (for instance, Context) andthen specify the classes that you want to access in the Import List input (for instance,javax.naming.*). Similarly, when using LJOs, make sure you import the appropriate classesusing the import command (for instance, import javax.naming.*).

com.bowstreet.WebApp.WebAppAccess

The WebAppAccess interface is arguably the most useful interface available in WPF, as it pro-vides access to a running instance of a WebApp—that is, the executed product of your buildersand Java methods (see Chapter 1, “Introduction to WebSphere Portlet Factory,” for a discussionof the WebApp in WPF). Methods defined in Method builders and inline Java calls automaticallyhave access to an object called webAppAccess (which implements the WebAppAccess inter-face), giving you access to the model that contains the method. To use this object in LJO methods,however, you need to pass the webAppAccess object into the desired methods as a parameter.

TIP

If you want to use the webAppAccess object in an LJO, you need to declare an argument oftype WebAppAccess as the first argument in an LJO method. When the LJO method iscalled from your model, WPF automatically passes the webAppAccess object as the firstargument.

To access the WebApp for a linked model (that is, a model accessible to your model via aLinked Model builder call), use this command:

webAppAccess.getLinkedModelInstance(“linkedModelBuilderCall”);

where linkedModelBuilderCall is the name of a Linked Model builder call in the current modelthat links to the WebApp that you would like to access. To get access to a WebApp outside thescope of the current model (that is, one that is not available through a link in the current model),use this command:

WebAppAccess remoteWebAppAccess =

�webAppAccess.getModelInstance(“modelPath/ModelName”, “”,

�false);

where the first parameter is the path and filename of the model you would like to access (relativeto the WebContent/WEB-INF/models directory). The second parameter is the profile set and pro-file combination that you would like to apply to the model (for example, Customer!Admin couldbe used to specify the Admin profile in the Customer profile set; alternatively, specify an empty

Java Application Programming Interfaces 203

Page 241: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

String (“”) to use the default settings). The third parameter is a Boolean value determiningwhether the WebAppAccess object is created as a singleton (a singleton is a class that can only beinstantiated once per JVM, which prevents multiple copies of the class from being created).

A description of some of the more useful methods in the WebAppAccess interface, alongwith examples of how to use these methods with the webAppAccess object, are described inTable 8.1. The full Javadoc for the WebAppAccess class is available in the WPF Designer help.

Table 8.1 WebAppAccess Useful Methods and Examples

Method Description Example

204 Chapter 8 Using Java in Portlets

java.lang.ObjectcallMethod(java.lang.Stringname)

Used to call another Javamethod in the WebApp whenno arguments are required.

webAppAccess.callMethod(“main”);

java.lang.ObjectcallMethod(java.lang.Stringname, java.lang.Object[] args)

Used to call another Javamethod in the WebApp whenarguments are required. Thearguments are passed in as anarray.

java.lang.String customerData[]= new java.lang.String[10];

webAppAccess.callMethod(“saveData”, customerData);

java.lang.ObjectcallMethod(java.lang.Stringname, java.lang.Object arg1,java.lang.Object arg2,java.lang.Object arg3,java.lang.Object arg4,java.lang.Object arg5)

Used to call another Javamethod in the WebApp whenarguments are required. Up tofive individual arguments can bepassed into the method.

java.lang.String customerData =“0001”;

webAppAccess.callMethod(“saveData”, customerData,“true”, 2);

java.lang.ObjectfireEvent(java.lang.StringeventName, java.lang.Object[]args)

Used to fire an event specifiedby an Event Declaration builder.Arguments are passed to theevent in an array.

java.lang.StringcustomerArguments[] = newString[10];

webAppAccess.fireEvent(“publishCustomerID”,customerArguments);

java.lang.ObjectfireEvent(java.lang.Objecttarget, java.lang.StringeventName, java.lang.Object[]args)

Used to fire an event to aspecific target. Arguments arepassed to the event in an array.

java.lang.StringcustomerArguments[] = newjava.lang.String[10];

webAppAccess.fireEvent(“customerModel”,“publishCustomerID”,customerArguments);

Page 242: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Java Application Programming Interfaces 205

javax.servlet.http.HttpServletRequestgetHttpServletRequest()

Gets a reference to thejavax.servlet.http.HttpServletRequest object for the currentuser request. This object isuseful for things like gettingcookies and sessioninformation.

javax.servlet.http.HttpServletRequest httpServletRequest =webAppAccess.getHttpServletRequest();

javax.servlet.http.Cookies[]cookie = httpServletRequest.getCookies();

javax.servlet.http.HttpServletResponsegetHttpServletResponse()

Gets a reference to thejavax.servlet.http.HttpServletResponse object for the currentuser request. This object isuseful for things like settingpage statuses and addingcookies.

javax.servlet.http.HttpServletResponse httpServletResponse= webAppAccess.getHttpServletResponse();

httpServletResponse.setStatus(httpServletResponse.SC_MOVED_TEMPORARILY);

com.bowstreet.webapp.RequestInputsgetRequestInputs()

Used to get all of the inputvalues for the current request.

com.bowstreet.webapp.RequestInputs requestInputs =webAppAccess.getRequestInputs();

java.lang.String value =requestInputs.getInputValue(“ID”);

com.bowstreet.webapp.util.UserInfogetUserInfo()

Used to get a handle to userinformation, such as the userID.

com.bowstreet.webapp.util.UserInfo userInfo =webAppAccess.getUserInfo();

java.lang.String id = userInfo.getUserID();

com.bowstreet.webapp.VariablesgetVariables()

Used to get all of the inputvalues for the current request.

com.bowstreet.webapp.Variables variables =webAppAccess.getVariables();

java.lang.String value =variables.getVariable(“ID”).getValue();

com.bowstreet.WebAppgetWebApp()

Gets a reference to the sharedWebApp from which allWebApp instances for aparticular model are created.Using this interface, you canretrieve such things as methodlists and data service lists, andalso add these elementsdynamically.

com.bowstreet.WebAppwebApp = webAppAccess.getWebApp();

java.util.Iterator iterator =WebApp. getDataServices();

Method Description Example

(continued)

Page 243: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

206 Chapter 8 Using Java in Portlets

void logError(java.lang.Stringmessage, java.lang.Throwableexception)

Logs an error in on the Javaconsole and in theSystemOut.log logfile.

java.lang.NumberFormatException nfe = new java.lang.NumberFormatException();

webAppAccess.logError(“Itemquantity is not a valid number.”,nfe);

java.lang.ObjectprocessAction(java.lang.Stringaction)

Used to invoke executable WPFartifacts, such as methods,actions, action lists, pages, orlinked models.

//to call an executable WPFartifact

webAppAccess.processAction(“builderName”);

//to consume a service operation

webAppAccess.processAction(“serviceCallName.invoke”);

void processPage(java.lang.String name)

Displays the output for aparticular page. Note thatmultiple processPage methodscan be used to display severalpages on the same screen, oneafter the other.

//for a page in the same model

webAppAccess.processPage(“page1”);

//for a page in a different model

webAppAccess.processPage(“linkedModelName.page1”);

Table 8.1 WebAppAccess Useful Methods and Examples (continued)

Method Description Example

com.bowstreet.webapp.Variables

The Variables interface provides access to the variables created by the Variable builder, enablingyou to both get and set variable values. You can get access to the variables in a WebApp by usingthe getVariables method of the WebAppAccess class.

To get the value of a String variable called id, you can use the following line:

java.lang.String value =

�webAppAccess.getVariables().getString(“id”);

To set the variable’s value, you can use this line:

webAppAccess.getVariables().setString(“id”, “newIDValue”);

Note that each variable data type has its own get and set methods, which are listed inTable 8.2. You can also retrieve the data type of a variable as a String, using a line similar to thefollowing:

java.lang.String variableType =

�webAppAccess.getVariables().getVariable(“id”).getType();

Page 244: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table 8.2 Variable Get and Set Methods

Data Type GetMethod SetMethod

Boolean getBoolean() setBoolean()

Double getDouble() setDouble()

Float getFloat() setFloat()

Int getInt() setInt()

Iterator getIterator() none

Long getLong() setLong()

Object getObject() setObject()

String getString() setString()

Xml getXml() setXml()

com.bowstreet.webapp.RequestInputs

The Variables interface is useful for getting variable values stored in WPF, but cannot be used toget the values or names of items on a form (such as the data entry fields created by a Data Pagebuilder). For this purpose, you need to use the RequestInputs interface.

The following code snippet shows you how to iterate through the inputs on a form, and thenwrite the names and values of these inputs to the SystemOut.log file:

java.util.Iterator names =

�webAppAccess.getRequestInputs().getInputNames();

while(names.hasNext())

{

//input name

String inputName = (String)names.next();

System.out.println(“Input name: “ + inputName);

//input value

String inputValue =

�webAppAccess.getRequestInputs().getInputValue(inputName);

System.out.println(“Input value: “ + inputValue);

}

Java Application Programming Interfaces 207

Page 245: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

com.bowstreet.util.IXml and com.bowstreet.util.XmlUtil

Another commonly used Java API, the IXml interface can be used to perform basic manipula-tions on XML documents. The IXml interface is discussed in more detail in Chapter 9. The othercommonly used XML interface is XmlUtil, which provides some additional functionality fordealing with XML (particularly for creating an XML document, parsing XML structures, andfinding an element within an XML document).

For example, to create a new XML document called Orders, you can use the followingcode:

try

{

IXml orders = XmlUtil.create(“Orders”);

}

catch (java.io.IOException e)

{

e.printStackTrace();

}

Notice that the code is enclosed in a try/catch block. This handles any IOExceptions thrownby the create method.

To create the same XML document based on a parsed text string, you can use this code:

try

{

IXml orders = XmlUtil.parseXml(“<Orders />”);

catch (java.io.IOException e)

{

e.printStackTrace();

}

To find an XML element called Item in the orders XML document, you can use thiscommand:

List results = XmlUtil.findElements(orders,

�“Orders/Sales/Item”)

where Sales/Item is an XPath expression (you must specify a valid XPath for the element you arelooking for inside the XML structure).

TIP

You can print IXml objects directly to the console, without needing to explicitly convert themto Strings first. For example, you can print the orders IXml variable to the console by usingthis line:

System.out.println(orders);

208 Chapter 8 Using Java in Portlets

Page 246: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

javax.servlet.http.HttpServletRequest and

javax.servlet.http.HttpServletResponse

The HttpServletRequest and HttpServletResponse interfaces are not specific to WPF, but theycan be quite useful in WPF development. In particular, you can use the HttpServletRequest inter-face to get objects (such as shared variable values) from the user’s current session, as shown inthe following:

String objectValue =

�webAppAccess.getHttpServletRequest().getSession().get

�“objectName”);

And you can add objects into the session as follows:

webAppAccess.getHttpServletRequest().getSession().put

�(“objectName”, “objectValue”);

This can give you a way to share user-specific variables between models (and even separateapplications), but you should use this feature sparingly to minimize your application’s memoryconsumption.

You can also remove objects from the session as follows:

webAppAccess.getHttpServletRequest().getSession().remove

�(“objectName”);

The HttpServletResponse interface is particularly useful for adding cookies for a user. Forexample, to add a cookie to store the ID of a purchased item, you can use the following code:

String id = “00001”;

Cookie cookie = new Cookie(“Purchase”, id);

webAppAccess.getHttpServletResponse().addCookie(cookie);

To access the cookie, you would then use the getCookies method of the HttpServletRequestinterface:

Cookie[] cookies =

�webAppAccess.getHttpServletRequest().getCookies();

for(i=0; i < cookies.length; i++)

{

Cookie cookie = cookies[i];

if (cookie.getName().equals(“Purchase”))

{

//cookie object now holds reference to Purchase cookie

}

}

Java Application Programming Interfaces 209

Page 247: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Java Beans

Java beans are Java classes that fulfill certain criteria and are intended to encapsulate a particularsubset of functionality. The major criteria that a Java class should satisfy to be considered a Javabean are as follows:

• The class must have a no argument constructor (a constructor is a method that is exe-cuted when a class is instantiated).

• The private properties of the class are exposed through public getter and setter methods.For example, a property called name would require a getName and setName method.

You can convert an ordinary Java class into a Java bean simply by making sure the classadheres to the criteria previously specified. Usually the class also implements the java.io.Serializ-able interface, which handles the storage of bean data (this is referred to as persistence).

Java beans are commonly used in Java development to represent business objects (that is,entities that are part of the structure of the business, such as orders, customers, and stock). InWPF, you don’t necessarily need to use Java beans because you have all of the prepackaged dataaccess builders available to directly access backend data sources. However, there are cases whereit might be preferable to use Java beans. For example, you might be connecting to a data sourcethat is not natively supported by WPF, you might want to execute some code before performingdata functions, or you want to reuse existing data implementations in Java beans. In these scenar-ios, you need to create an interface to the Java bean from WPF.

To use a Java bean in WPF, you can import the bean class into the WEB-INF/work/sourceor WEB-INF/work/lib directory, add a Linked Java Object builder call to link to the class, andthen use one or more Data Page builders to create a UI for the bean. You can also automaticallycreate a UI for collections of beans using the Bean Master Detail builder. However, this buildershould be used with caution because it mixes the presentation layer of your application with yourdata layer (that is, it is used to control both your data and how it is presented to end users). Ideally,Java beans should be hidden behind a service provider, so they can be changed without affectingthe presentation of your application.

The next few sections describe how to build a simple shopping cart application, whichstores the name and quantity of purchased items for a particular user in a Java bean. An ID isautomatically assigned to each item in the cart, which can also be used to edit and delete cartitems. A combination of Linked Java Objects, Action Lists, and Method builders is used to inter-act with the Java bean.

Creating a Java Bean and Bean Manager

The first step in creating your shopping cart portlet is to create a Java bean to interact with indi-vidual shopping cart items and another class to manage collections of these beans in a shoppingcart. Before you proceed with this section, you need a WPF project to house the models and Javaclasses for the shopping cart portlet. If you have a project from a previous chapter, you can use

210 Chapter 8 Using Java in Portlets

Page 248: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

that; otherwise, you should create a new WPF project (for more information on creating projects,see Chapter 1). The project will be published as a WAR file and deployed to a portal server, andyou should also deploy the application to a local application server for testing. (You can use theportal server if it is running on your local machine; otherwise, it is recommended that you use theIBM WebSphere Application Server Community Edition server (WAS CE) that comes with WPF.)

TIP

When creating a WPF project, the Java Settings screen in the wizard enables you configuresettings that affect the use of Java in your application. The first tab on this screen, Source,enables you to configure folder locations for all the editable Java source code in your project.Java source files in the default source directory (WebContent/WEB-INF/work/source) areautomatically compiled into the WebContent/WEB-INF/work/classes directory wheneverthey are saved. The Projects tab lets you access resources from other projects on the work-space, and the Libraries tab lists all of the JARs that will be added to your project when it iscreated. Finally, the Order and Export tab lets you do two things: specify files that will beavailable to other projects when the project is imported, and specify the order in which JARfiles are accessed in your project. If you have the same class defined in multiple JARs (assometimes happens), you should put the JAR containing the correct class higher in the listthan the JARs containing the incorrect classes (although you should avoid defining thesame class in more than one JAR if possible).

You generally don’t need to change anything on the Java Settings screen unless you arereferencing other projects, or you are using a customized set of JAR files.

Creating a Shopping Cart Item Bean

Create a Java source file for a shopping cart item Java bean by clicking File, New, Class in theWPF Designer. For the package, type com.ibm (substituting your own company name for ibm),specify ShoppingCartItem as the Name, and then click Finish. The package com.ibm is usedthroughout this chapter, but in each case you should substitute your own company name for ibm.

You now need to edit the contents of the new Java class so they read as shown in the follow-ing example. The fastest way to do this is to add the bolded code manually, and then right-clickon the source file in the Project Explorer view. Select Source, Generate Getters and Setters, whichopens the Generate Getters and Setters dialog. After this dialog is open, select the boxes to creategetters and setters for the id, name, and quantity properties, and then click OK. This should auto-matically add in the get and set methods in the following code. Note that you can also copy thiscode from the ShoppingCartItem.java file, which is available for download from ibmpressbooks.com/title/9780137134465, under the Chapter 8 folder.

package com.ibm;

public class ShoppingCartItem implements java.io.Serializable

Creating a Java Bean and Bean Manager 211

Page 249: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

{

//properties

private String id;

private String name;

private int quantity;

//no argument constructor

public ShoppingCartItem()

{

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getQuantity() {

return quantity;

}

public void setQuantity(int quantity) {

this.quantity = quantity;

}

}

The bean has three private properties: id, name, and quantity, which are changed via sepa-rate get and set methods. The bean also has a constructor with no arguments, which enables youto create new shopping cart items. Notice also that the bean implements the java.io.Serializableinterface; this enables the bean data to be serialized (that is, persisted). The data is only serializeduntil the user’s session is terminated (although it is possible to persist data beyond the lifetime ofthe user’s session).

212 Chapter 8 Using Java in Portlets

Page 250: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

In the Problems view, you see the following warning (unless you have filtered out thesewarnings in your IDE preferences):

The serializable class ShoppingCartItem does not declare a

static final serialVersionUID field of type long

This message declares that you should set an identifying field for the class, so that when theclass is modified, the Java serialization engine will recognize different versions of the same class.To add this field, place the cursor somewhere inside the line that begins public class Shop-pingCartItem and press Ctrl+1. Select Add Generated Serial Version ID from the contextmenu. You should see an ID field added to the top of the class, similar to the following:

/**

*

*/

private static final long serialVersionUID =

�-7554150284752194927L;

Save the ShoppingCartItem bean when you are finished.

Creating a Shopping Cart ItemManager

Now you need to create a class to manage collections of ShoppingCartItem beans for each user.This new class holds an ArrayList of shopping cart item beans called shoppingCart.

Create a new Java class called ShoppingCartItemManager in the com.ibm package(substituting ibm for your own company name), and fill out the class as shown in the following(note that you can copy this code from the ShoppingCartItemManager.java file, available fordownload from ibmpressbooks.com/title/9780137134465, under the Chapter 8 folder):

package com.ibm;

import java.util.ArrayList;

import java.util.Iterator;

public class ShoppingCartItemManager

{

//properties

private static ArrayList shoppingCart = new ArrayList();

private static int idCounter=0;

//get method for a shopping cart

public static ArrayList getShoppingCart()

{

return shoppingCart;

Creating a Java Bean and Bean Manager 213

Page 251: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

}

//create blank shopping cart item

public static ShoppingCartItem createShoppingCartItem()

{

return new ShoppingCartItem();

}

//add newly created item to shopping cart

public static void addShoppingCartItem(ShoppingCartItem

�toAdd)

{

//increment Id counter and set Id of new item

idCounter++;

toAdd.setId(Integer.toString(idCounter));

//add new item

shoppingCart.add(toAdd);

}

//retrieves a particular item from the shopping cart

public static ShoppingCartItem getShoppingCartItem(String

�toGet)

{

Iterator i = shoppingCart.iterator();

while (i.hasNext())

{

ShoppingCartItem item = (ShoppingCartItem)i.next();

if (item.getId().equals(toGet))

{

return item;

}

}

return null;

}

//updates a particular item in the shopping cart

public static void updateShoppingCartItem(ShoppingCartItem

�toUpdate)

{

Iterator i = shoppingCart.iterator();

while (i.hasNext())

214 Chapter 8 Using Java in Portlets

Page 252: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

{

ShoppingCartItem item = (ShoppingCartItem)i.next();

if (item.getId().equals(toUpdate.getId()))

{

item.setName(toUpdate.getName());

item.setQuantity(toUpdate.getQuantity());

return;

}

}

}

//delete method for a shopping cart item (can be used with

�Bean Master Detail builder)

public static void deleteShoppingCartItem(ShoppingCartItem

�toDelete)

{

shoppingCart.remove(toDelete);

}

//delete method for a shopping cart item

public static void deleteShoppingCartItem(String toDelete)

{

Iterator i = shoppingCart.iterator();

while (i.hasNext())

{

ShoppingCartItem item = (ShoppingCartItem)i.next();

if (item.getId().equals(toDelete))

{

shoppingCart.remove(item);

return;

}

}

}

//deletes every item in the shopping cart

public static void clearShoppingCart()

{

shoppingCart.removeAll(shoppingCart);

idCounter = 0;

}

}

Creating a Java Bean and Bean Manager 215

Page 253: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This class holds an ArrayList of ShoppingCartItem objects, called shoppingCart, as well asa counter that is used to generate IDs for each item. These IDs are then used to look up particularitems in the shopping cart. Separate methods are provided for retrieving, adding, editing, anddeleting items from the shopping cart. Note that each method and property in the class is declaredas static, which means that they apply to the class as a whole rather than to a particular instance ofthe class. (However, note that each user accesses a different copy of the class, which also meansthat each user has his own shopping cart). In fact, you don’t even need an instance of the class tocall these methods, which makes the job of calling each method a little simpler.

Save the file when you are finished.

TIP

There is nothing preventing you from using non-static methods in Java code that isaccessed from WPF. When using non-static methods, keep in mind that you need to createan instance of the class before it can be used (for instance, ShoppingCartItemManager s =new ShoppingCartItemManager). Also, to create instances of a class, you need to declarea constructor method (as done in the ShoppingCartItem class).

Your IDE automatically creates compiled .class files of your java files whenever you savethem. If you have any errors in the Problems view at this point, check that you have entered theJava in this section correctly.

The next section describes how to create an interface for these classes via a WPF serviceprovider model.

Creating a Service Provider

In this section, you build a service provider model to interface with the Java classes created in theprevious section. The service provider will have operations for clearing and viewing the cart, andviewing, adding, updating, and deleting an item from the cart. To achieve this, the followingbuilders are used:

• Service Definition

• Linked Java Object

• Java/XML Converter

• Comment (x6)

• Method (x5)

• Service Operation (x6)

Note that although the order of builder calls is usually not important, some of the buildercalls in this chapter need to be in a specific order. This is because some of the builder calls requirecertain things to be built by the time their build methods run (when the WebApp is generated). In

216 Chapter 8 Using Java in Portlets

Page 254: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

the following example (as with other examples that use the same builders), the Service Definitionbuilder call must come before the Service Operation builder calls, and the Service Operationbuilder calls must come after the Methods and Action Lists that they access (otherwise, you willget errors indicating that these resources are unavailable).

Creating a Model

Create a new model called shoppingCartService in your project, under the folder WEB-INF/models/chapter08. The model should be based on the Empty template, which creates amodel with no builder calls in it.

You now need to add a number of builder calls to the model to make it a service provider.

Defining the Service

The first step is to add several general purpose builders that are used across each operation in theservice. Add a Service Definition builder call to the model by selecting Service Definition fromthe Builder Palette and then clicking OK (you can open the Builder Palette by clicking the icon in the Outline view). Name the builder call shoppingCartService, and expand the Test-ing Support section of the builder call. Finally, enable the Add Testing Support checkbox andsave the builder call when you are finished.

Adding a Linked Java Object

Now add a Linked Java Object builder call to the model and name it shoppingCartItemMan-ager. For the Class Name, select com.ibm.ShoppingCartItemManager from the Select Actiondialog (swapping ibm for your own company name). This builder call can be used to refer to themethods of the ShoppingCartItemManager class within the shoppingCartService model. Save thebuilder call when you are finished.

Adding a Java to XML Converter

Add a Java/XML Converter builder to the model and name it shoppingCartConverter. Thisbuilder call is used to convert bean data to XML (and vice-versa).

Change the Reference Type input to Collection of Objects, as you will be working with acollection of shopping cart item beans. For the Data Reference input, you need to specify a vari-able or method that returns the collection of beans that you want to use. In this example, the col-lection is provided in the form of the shoppingCart ArrayList, which you can access via the LJOcreated in the previous step. To do this, open the Choose Reference dialog for the Data Referenceinput (by clicking the ellipsis button to the right of the input), and specify the getShoppingCartmethod as shown in Figure 8.3.

Now select the com.ibm.ShoppingCartItem class for the Class Name input (by using thepicker provided by the ellipsis button to the right of the field), and then in the Variable input, typethe name shoppingCartVariable (once again, remember to swap ibm for your own companyname). This creates a temporary variable called shoppingCartVariable to store the results of XMLconversions.

Creating a Service Provider 217

Page 255: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 8.3 Selecting the getShoppingCart method.

Finally, expand the XML Options section and change the Top-level Tag Name input toShoppingCart, and the Row Tag Name input to ShoppingCartItem. This defines XML ele-ment names when WPF creates XML from shopping item beans. Save the builder call when youare finished.

Clearing a Shopping Cart

Add a Comment builder call to the model, and name it Clear shopping cart. This does notactually affect any of the other builder calls, but it does make your model easier to read. The nextbuilder call in the model provides functionality for clearing all items from a shopping cart.

Add a Service Operation builder call to the model and name it clearShoppingCart.Specify the Operation Name as clearShoppingCart, and then for the Action to Call input,open the Select Action dialog and select the clearShoppingCart Method of the shoppingCartItem-Manager LJO, as shown in Figure 8.4.

218 Chapter 8 Using Java in Portlets

Page 256: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 8.4 Selecting the clearShoppingCart method.

This runs the shoppingCartItemManager LJO’s clearShoppingCart method. Note that thereis no need to create an instance of the shoppingCartItemManager, as you are accessing a staticmethod. Now specify the Data Service as shoppingCartService. Because this operation doesn’trequire any inputs or return any results, specify ‘No Inputs’ for the Input Structure Handling inputin the Operation Inputs section and ‘No Results’ for the Result Structure Handling input in theOperation Results section. Save the builder call when you are finished.

Viewing a Shopping Cart

Add a Comment builder call to the model, and name it View shopping cart. The next fewbuilder calls in the model provide functionality for viewing the contents of a shopping cart.

Add a Method builder call to the model and name it viewShoppingCart. Change theReturn Type of the builder call to IXml, and then type the following code into the Method Bodyinput:

Creating a Service Provider 219

Page 257: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

{

//set shopping cart variable from bean

webAppAccess.getVariables().setObject(“shoppingCartVariable”,

�webAppAccess.callMethod(“shoppingCartItemManager.getShoppingCart”));

//return shopping cart variable

return shoppingCartConverterConvertToXML(webAppAccess);

}

This retrieves the shopping cart from the shopping cart item manager and stores it in theshoppingCartVariable variable. The ConvertToXML method of the Java/XML Converter builderis then run, which converts the contents of the shoppingCartVariable variable into XML (remem-ber that this variable is specified in the Java/XML Converter builder itself, so there is no need topass the variable as a parameter). The result is then returned to the caller.

Save the builder call when you are finished.

TIP

In WPF, many of the default builders provide methods that surface additional functionality,and these methods are of the following form:

{BuilderCallName}{BuilderMethod}

For example, the ConvertToXML method of the shoppingCartConverter builder call is runwith the command shoppingCartConverterConvertToXML.

Add another Service Operation builder call to the model and name it viewShoppingCart.Specify the Data Service as shoppingCartService, and then type viewShoppingCart for theOperation Name. For the Action to Call input, select the viewShoppingCart method you just cre-ated from under the Methods section of the Select Action dialog.

This operation doesn’t require any inputs, so specify No Inputs for the Input StructureHandling input. However, the operation should return an XML shopping cart object containing asequence of shopping cart items. In some cases, you are able to use the result structure from thecalled action as the structure of the operation’s result, but you can’t do this when the actionreturns an XML document where the schema is not explicitly specified. In the example, you havereturned a non-schema typed IXml object (you cannot return a schema typed variable from aMethod builder call), so you need to manually specify the schema in the Service Operationbuilder call.

Change the Result Structure Handling input to ‘Specify result schema’, and then selectshoppingCartConverterSchema/ShoppingCart for the Result Schema input (this is the top-level

220 Chapter 8 Using Java in Portlets

Page 258: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

element created by the Java/XML Converter builder call). Save the builder call when you arefinished.

Viewing a Shopping Cart Item

Add a Comment builder call to the model and name it View item. The next few builder calls inthe model provide functionality for viewing an individual item in the shopping cart.

Add a Method builder call to the model and name it viewShoppingCartItem. Add anargument to the Arguments input in the Arguments section, called itemID of type String. Changethe Return Type of the builder call to IXml, and then type the following code into the MethodBody input:

{

//get shopping cart item

com.ibm.ShoppingCartItem shoppingCartItem =

�(com.ibm.ShoppingCartItem)webAppAccess.callMethod(“shopping

�CartItemManager.getShoppingCartItem”, itemID);

//return XML representation of shopping cart item

return (IXml)webAppAccess.callMethod

�(“shoppingCartConverterConvertObjectToXML”,

�shoppingCartItem);

}

This retrieves an item from the shopping cart based on the ID passed in to the Methodbuilder call. The resulting shoppingCartItem bean is converted into XML using the ConvertOb-jectToXML method of the Java/XML Converter builder, and then returns this XML to the caller.Note that in this case, the shoppingCartItem has been specified as an argument to the ConvertOb-jectToXML method, rather than changing the value of the shoppingCartVariable variable andthen using the ConvertToXML method with no arguments. This is necessary because the XMLreturned is an individual item, and the shoppingCartVariable XML holds a sequence of items.

Save the builder call when you are finished.Add another Service Operation builder call to the model and name it viewShoppingCar-

tItem. Specify the Data Service as shoppingCartService, then type viewShopping

CartItem for the Operation Name. Select the viewShoppingCartItem Method for the Action toCall input as well.

Specify ‘Use Structure from Called Action’ for the Input Structure Handling input, so thatthe operation takes a single String input as defined in the viewShoppingCartItem Method buildercall. For the Result Structure Handling input, select Specify Result Schema and then select shop-pingCartConverterSchema/ShoppingCartItem for the Result Schema input (this is the row-levelelement created by the Java/XML Converter builder call).

Save the builder call when you are finished.

Creating a Service Provider 221

Page 259: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Shopping Cart Item

Add a Comment builder call to the model, and name it Add item. The next few builder calls inthe model provide functionality for adding an item to the shopping cart.

Add a Method builder call to the model and name it addShoppingCartItem. Add anargument to the Arguments input in the Arguments section, called toAdd of type IXml. Changethe Return Type of the builder call to void, and then type the following code into the MethodBody input:

{

//create new shopping cart item bean

ShoppingCartItem shoppingCartItem = new ShoppingCartItem();

//convert ‘toAdd’ object to bean

webAppAccess.callMethod(“shoppingCartConverterConvertObject

�FromXML”, shoppingCartItem, toAdd);

//add new bean to shopping cart

webAppAccess.callMethod(“shoppingCartItemManager.addShopping

�CartItem”, shoppingCartItem);

}

This creates a new, blank shopping cart item, and then sets it to a Java representation of thetoAdd IXml object using the ConvertObjectToXML method of the Java/XML Converter builder.The resulting bean is then added to the shopping cart via the shoppingCartItemManager.

Notice in the preceding code that the ShoppingCartItem class has not been fully qualifiedas it has been previously. Save the builder call now, and you will notice that this causes an error inyour application. To remove this error, expand the Import List section of the builder call and enterthe class com.ibm.ShoppingCartItem into the Import List input (swapping ibm for your owncompany name). Save the builder call, and the error should be removed from the Problems view.Although it is really a matter of preference how you choose to reference classes (particularly withsmall and simple methods), keep in mind that as your methods get larger, fully qualified classes inthe method body can make your code more difficult to read.

Add another Service Operation builder call to the model and name it addShoppingCartItem. Specify the Data Service as shoppingCartService, and then type addShoppingCartItem for the Operation Name. Select the addShoppingCartItem Method for the Action toCall input, and then select ‘Specify input schema’ for the Input Structure Handling input. For theInput Schema input, select shoppingCartConverterSchema/ShoppingCartItem. This declares thestructure of the operation’s input to be a single shopping cart item element, as defined by the rowelement of the Java/XML Converter builder call. For the Result Structure Handling input, selectNo Results.

Save the builder call when you are finished.

222 Chapter 8 Using Java in Portlets

Page 260: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Updating a Shopping Cart Item

Add a Comment builder call to the model, and name it Update item. The next few builder callsin the model provides functionality for updating an item in the shopping cart.

Add a Method builder call to the model and name it updateShoppingCartItem. Add anargument to the Arguments input in the Arguments section, called toUpdate of type IXml.Change the Return Type of the builder call to void, and then type the following code into theMethod Body input:

{

//create new shopping cart item bean

com.ibm.ShoppingCartItem shoppingCartItem = new

�com.ibm.ShoppingCartItem();

//convert ‘toUpdate’ object to bean

webAppAccess.callMethod(“shoppingCartConverterConvertObject

�FromXML”, shoppingCartItem, toUpdate);

//update shopping cart with new bean

webAppAccess.callMethod(“shoppingCartItemManager.update

�ShoppingCartItem”, shoppingCartItem);

}

This creates a new shopping cart item, and then sets it to the value of the converted toUp-date IXml object passed in to the Method builder call. The shopping cart is then updated with thenew item. Save the builder call when you are finished.

Now add another Service Operation builder call to the model and name it updateShop-pingCartItem. Specify the Data Service as shoppingCartService, and then type updateShop-pingCartItem for the Operation Name input. Select the updateShoppingCartItem Method forthe Action to Call input, and then select ‘Specify Input Schema’ for the Input Structure Handlinginput. After this is done, select shoppingCartConverterSchema/ShoppingCartItem for the InputSchema input. This declares the structure of the operation’s input to be a single shopping cartitem element. For the Result Structure Handling input, select No Results.

Save the builder call when you are finished.

Deleting a Shopping Cart Item

Add a Comment builder call to the model, and name it Delete item. The next few builder callsin the model provide functionality for deleting an item from the shopping cart.

Add a Method builder call to the model and name it deleteShoppingCartItem. Add anargument to the Arguments input in the Arguments section, called itemID of type String. Changethe Return Type of the builder call to void, and then type the following code into the MethodBody input:

Creating a Service Provider 223

Page 261: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

{

//delete shopping cart item

webAppAccess.callMethod(“shoppingCartItemManager.delete

�ShoppingCartItem”, itemID);

}

This deletes an item from the shopping cart based on the ID passed in to the Method buildercall. Save the builder call when you are finished.

Now add the final Service Operation builder call to the model and name it deleteShop-pingCartItem. Specify the Data Service as shoppingCartService, and then type deleteShop-pingCartItem for the Operation Name. For the Action to Call input, select the deleteShoppingCartItem method.

Specify ‘Use Structure from Called Action’ for the Input Structure Handling input, so thatthe operation takes a single String input as defined in the deleteShoppingCartItem method buildercall. For the Result Structure Handling input, select No Results. Save the builder call when youare finished.

Your service provider is now finished and ready to test.

Testing the Service Provider

Because you enabled testing support on the Service Definition builder call, WPF automaticallygenerates test pages for your service provider when you run it in a browser.

To test the service provider, first run the shoppingCartService model from the WPFDesigner by clicking the icon on the toolbar. This runs the currently active model (such asshoppingCartService) with the last run configuration you used. If you have not set up a run con-figuration before, you are prompted to do so—create a new configuration under the WebSpherePortlet Factory Model category (if you want more information on setting up a run configuration,see the “Testing the Application” section in Chapter 1).

After you run shoppingCartService, you should see the index test page in your default Webbrowser, as shown in Figure 8.5. This screen lists all of the operations available on the shopping-CartService service.

224 Chapter 8 Using Java in Portlets

Figure 8.5 Index test page from the shoppingCartService model.

Page 262: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the Service Provider 225

Testing the addShoppingCartItem Operation

Because the shopping cart is empty by default, you need to test the operations in a particularorder. First, test the addShoppingCartItem operation by adding a few items to the shopping cart.To do this, click the addShoppingCartItem link. You should see a data entry screen as shown inFigure 8.6. Enter a sample name and quantity, and then click Submit Query (note that there is noneed to enter an ID, as it is automatically overwritten by the addShoppingCartItem method of theShoppingCartItemManager class). The quantity should be a numeric value; otherwise, you willreceive errors (note that the data type of these inputs are not validated—validation of data inputsis covered in Chapter 11, “Field Validation, Formatting, and Translation”). Click the Back buttonwhen you are finished, and add one or two more items to the cart.

Figure 8.6 Testing the addShoppingCart operation.

Testing the viewShoppingCart Operation

To test that the items were added and that they can be display correctly, click the viewShopping-Cart link. You should see a list of the items similar to that shown in Figure 8.7. If not, check thatyou don’t have any errors showing in the Problems view in the IDE, and that you have completedall of the steps in the previous section correctly.

Click Back to return to the index page.

Figure 8.7 Testing that items can be added and viewed in a list.

Testing the viewShoppingCartItem Operation

Click on the viewShoppingCartItem link, and enter the ID of one of the items you just created(the IDs are in ascending order, starting at 1). Click the Submit Query button and you should seeoutput similar to that shown in Figure 8.8. Return to the index page.

Page 263: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

226 Chapter 8 Using Java in Portlets

Figure 8.8 Testing that individual items can be viewed.

Testing the updateShoppingCartItem Operation

Click the updateShoppingCartItem link and enter an ID of an existing item. Now enter a newName and Quantity for the item (different to the previous values the item had) and click the Sub-mit Query button. Return to the index page and run the viewShoppingCartItem operation. The listof items should reflect the new values of the item just updated.

Testing the deleteShoppingCartItem Operation

To test the deleteShoppingCartItem operation, click the deleteShoppingCartItem link. Enter the IDof an already existing item and click the Submit Query button. Return to the index page and run theviewShoppingCartItem operation. The list of items should no longer display the item just deleted.

Testing the clearShoppingCart Operation

For the final test, click on the clearShoppingCart link. When you return to the index page and runthe viewShoppingCartItem operation, the list of items in the cart should now be empty. Close theshoppingCartService model when you’ve finished testing it.

You now have a service provider that interacts with a collection of shopping cart item Javabeans. The next section walks you through creating a service consumer model, which communi-cates with the shoppingCartService model and is surfaced to a portal server as a portlet.

Creating a Shopping Cart Portlet

In this section, you build a shopping cart portlet to consume the shopping cart service. The portletprovides a user interface to interact with a shopping cart (that is, to view, edit, add, and deleteshopping cart items). A screenshot of the portlet is shown later in Figure 8.18.

Creating a Model

To add the shopping cart portlet, select File, New, WebSphere Portlet Factory Model from the Filemenu to bring up the WebSphere Portlet Factory Model dialog. On the next screen, select your WPFproject and click Next. The next screen lists different types of models WPF can create for you auto-matically. You can create service consumers in WPF two ways: the first is to let WPF create one foryou (which you can do by using the List and Detail Service Consumer option in the Select Modelwizard), and the second is to create the service consumer manually. The List and Detail ServiceConsumer gives you everything you need in this example, so select it and click Next.

Page 264: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The List and Detail Service Consumer automatically surfaces your model as a portlet via aPortlet Adapter builder call. Specify the name of the portlet on the next screen as shoppingCart(this name is also used to name the other builder calls in your model). Also, specify the serviceprovider shoppingCartService you created in the previous section. Click Next when you arefinished.

The next screen enables you to specify the service operation that is used to provide the listof shopping cart items. Select viewShoppingCart and click Next. On the next screen, make surethe Create Link to Details checkbox is enabled, and then select Id for the Details Link Columnfield. Change the Details Action Type to ‘Display Data from Another Operation in this Service’,and then enter viewShoppingCartItem into the Details Operation input. These settings con-vert all of the values in the ID column in the shopping cart item list into clickable links. When auser clicks on the link, a value identifying the item is passed to the viewShoppingCartItem opera-tion, and the results are displayed to the screen.

Click Next, and you should see some settings enabling you to configure the value that willuniquely identify each shopping cart item for the viewShoppingCartItem operation. Make surethe settings appear as shown in Figure 8.9, and then click Next. This uses the ID of the currentlyselected row to identify a shopping cart item when it is clicked.

Creating a Shopping Cart Portlet 227

Figure 8.9 Overriding inputs for each shopping cart.

Page 265: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

You now need to name your model. Type shoppingCart, and make sure the model is cre-ated in the directory models/chapter08. Click Finish. This creates a new model called shopping-Cart in your WPF project, and opens the model in the Model Editor and Outline view.

Configuring the Portlet Adapter

The shoppingCart model contains three builder calls: a Portlet Adapter, a Service Consumer, anda View & Form. The Portlet Adapter builder converts the model into a portlet, so that it can beviewed inside a portal (note that if you make any changes to this builder call—including thechanges you are about to make—you need to rebuild the deployed application before you can seethe results of the changes. For more information on this process, see the example in Chapter 1).The Service Consumer builder makes the operations in the shoppingCartService service availablein the model, and the View & Form builder displays any list and detail data in the model tothe screen. The View & Form builder also enables you to do some basic manipulation of how thedata is displayed (the View & Form builder is discussed in Chapter 5, “Customizing PortletAppearance”).

The builder calls don’t require any configuration in this example, except for two smallchanges to the Portlet Adapter builder call. Double-click the Portlet Adapter builder call to open itin the Model Editor, and then change the Portlet Title to Shopping Cart and the PortletDescription to Used to interact with a shopping cart. Save the builder call when youare finished. The Portlet Title identifies the portlet inside the portal (it is actually displayed in thetitle bar of the portlet), and the Portlet Description appears on various administration screensinside the portal.

You now need to add the following builder calls to the model to provide the portlet with itsfunctionality:

• Action list (x2)

• Comment (x3)

• Input form

• Button (x3)

Implementing the updateShoppingCartItem Operation

To add update support to the model, open the View & Form builder call, and expand the UpdatePage Support section. Enable the Create Update Page checkbox, and then specify DataServices/shoppingCart/updateShoppingCartItem for the Update Method input that appears underneath thecheckbox. This creates an update form for each item, and then executes the updateShoppingCar-tItem operation whenever an item is saved (by default, the input values on the form are sent in anXML object as the input to the operation). Also, change the Update Next Action input to shop-pingCartView_ShowResults, which re-runs the viewShoppingCartItem operation to refresh thecart item list, and then displays the refreshed shoppingCartView_ViewPage page. Save thebuilder call when you are finished.

228 Chapter 8 Using Java in Portlets

Page 266: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Because the View & Form builder does not automatically create an interface for adding newitems, you need to add a separate builder call to the model for this purpose. Add an Input Form tothe model and name it addItemForm. Enter the Input Submit Operation input as DataServices/shoppingCart/addShoppingCartItem, and then specify shoppingCartView_ShowResults as theInput Next Action. This consumes the addShoppingCartItem operation when an item is savedusing the input form, and then refreshes the shopping cart after the save is finished (which alsoreturns control to the item list page). Also, expand the Advanced section at the bottom of thebuilder, and disable the Generate Main checkbox so that an extra main Action List is not created(you are already using the main Action List created by the View & Form).

Leave the default settings for the rest of the builder call, and save the builder call when youare finished.

Implementing the addShoppingCartItem Operation

Now add a Button builder call to the model, which provides a means for users to open the inputform. Name the builder call addShoppingCartItem, and then fill out the Page Location sectionof the builder call as shown in Figure 8.10. This adds the button to a new tag called add_buttonafter the back_button tag, which automatically appears at the bottom of the list screen (eventhough the back button itself is not visible).

Creating a Shopping Cart Portlet 229

Figure 8.10 Configuring the page location for the Add item button.

For the label of the button, enter Add item, and then change the Action Type to ‘Link to anAction.’ Specify the Action as addItemForm_InputPage, which opens the input page createdin the previous step. Save the builder call when you are finished.

Implementing the clearShoppingCart Operation

Add a Comment builder call to the model, and name it Clear cart. The next few builder calls inthe model provide functionality for clearing the contents of a shopping cart. Now add anotherAction List builder call to the model, which you use to define the sequence of actions to be exe-cuted when the shopping cart is cleared. Name the Action List clearShoppingCart, and thenspecify DataServices/shoppingCart/clearShoppingCart as the first action. This clears the contentsof the user’s shopping cart. Then specify shoppingCartView_ShowResults for the second opera-tion, which refreshes the item list and displays the shoppingCartView_ViewPage page. Save thebuilder call when you are finished.

Page 267: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Add a Button builder call to the model and name it clearShoppingCart. This button pro-vides users with a means to access the clearShoppingCart Action List and is displayed immedi-ately after the Add item button on the item view page.

Fill out the Page Location section of the builder as shown in Figure 8.11.

230 Chapter 8 Using Java in Portlets

Figure 8.11 Configuring the page location for the Clear cart button.

Type Clear cart for the Label input, and then change the Action Type to ‘Link to anAction.’ Specify the Action as clearShoppingCart, which executes the Action List created in theprevious step. Save the builder call when you are finished.

Implementing the deleteShoppingCartItem Operation

The final piece of functionality is the delete operation. Add a Comment builder call to the model, and name it Delete item. The next few builder

calls in the model provide functionality for deleting an item from a shopping cart. Now addanother Action List to the model and name it deleteShoppingCartItem. The first action in theActions input needs to set the value of the itemID argument from the deleteShoppingCartItemoperation to the ID of the currently selected item. To do this, click the ellipsis button on the firstrow of the Actions input and select Special, Assignment. For the Target variable, specify theitemID of the deleteShoppingCartItem operation, as shown in Figure 8.12.

For the Source variable, specify the ID of the currently selected row as shown in Figure8.13. Click OK to accept your settings and return to the Action List builder call.

For the second action, specify DataServices/shoppingCart/deleteShoppingCartItem. Thiscalls the deleteShoppingCartItem operation, using the value set in the previous action as an input.Finally, specify shoppingCartView_ShowResults for the third operation, which updates the shop-ping cart and displays the view page created by the View & Form builder. Save the builder callwhen you are finished.

Page 268: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Shopping Cart Portlet 231

Figure 8.12 Assigning a target field.

Figure 8.13 Assigning a source field.

Page 269: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Add a Button builder call to the model, naming it deleteShoppingCartItem. This but-ton provides users with a means to access the deleteShoppingCartItem Action List and is dis-played immediately after the Back button on the detail page for each shopping cart item.

Fill out the Page Location section of the builder as shown in Figure 8.14.

232 Chapter 8 Using Java in Portlets

Figure 8.14 Configuring the page location for the Delete item button.

Type Delete item for the Label input, and then change the Action Type to ‘Link to anAction.’ Specify the Action as deleteShoppingCartItem, which executes the Action List created inthe previous step. Save the builder call when you are finished.

Your test portlet is now finished, and ready to test.

Testing the Shopping Cart Portlet

To test the shoppingCart portlet, first run the shoppingCart model from the WPF Designer. Afteryou have run the shoppingCart model, you should see an empty list of shopping cart items, aswell as several buttons for interacting with the shopping cart (see Figure 8.15).

Figure 8.15 The default screen for the shoppingCart model.

Testing the Add Item Button

Click on the Add Item button to add a new item to your shopping cart. Enter some sample data forthe Name and Quantity on the input screen that follows (keep in mind that the ID is overwrittenby the ShoppingCartManager class, so there is no need to enter one in) and click the Submit but-ton. You are returned to the default list screen, and the new item should appear in the item list(similar to the screenshot in Figure 8.16). Add one or two additional items to the list for testing.

Page 270: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Shopping Cart Portlet 233

Figure 8.16 Adding a shopping cart item.

Testing the Edit Item Button

Click on the ID column for one of the items you just created, and you should see a detail page forthat item similar to that shown in Figure 8.17. Click the Edit button to bring up an edit page forthe item (similar to the input page seen when adding a shopping cart item) and make a change tothe Name or Quantity of the item (you can’t change the ID of the item). You are returned to thedefault list screen, and the modified item details appear in the item list.

Figure 8.17 Item detail page.

Testing the Delete Item Button

To test the delete functionality, open one of the items you created and then click the Delete Itembutton. You are returned to the list screen, and the item no longer displays in the list.

Testing the Clear Cart Button

To test that you can clear the entire contents of the shopping cart, click the Clear Cart button. Thescreen should refresh and the list should now be empty.

After you have tested the shoppingCart model, you should rebuild your application on theportal server (for instructions on how to do this, see the example in Chapter 1), after which youare able to view the shoppingCart model as a portlet on the portal server. After you have added theshoppingCart portlet to a page in the portal, it should appear as shown in Figure 8.18.

The next section discusses how you can package Java files in your WPF applications usingJAR files.

Page 271: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

234 Chapter 8 Using Java in Portlets

Figure 8.18 The Shopping Cart portlet.

Java Archives

Java Archives (JARs) are class file libraries that your project can utilize to take advantage of cer-tain functionality. A typical WPF project employs numerous JAR files, which are used behind thescenes to facilitate such things as logging, XML manipulation, and builder generation routines.You can also import your own JAR files into a WPF project. If you have a collection of Javaclasses that you would like to distribute to others (or simply want to package together for ease ofuse), JAR files are a convenient way to achieve this. You can access Java classes contained in JARfiles directly from inside builder calls or other Java code.

TIP

You can package Java source files into a JAR file by selecting Export from the File menu inthe WPF Designer, and then choosing JAR from under the Java heading.

By default, WPF projects store all their JARs in the WebContent/WEB-INF/lib and Web-Content/WEB-INF/work/lib directories. If you use the Project Explorer view to browse thesedirectories, you can see that the only files that appear are the ones that are not on the build path.To view a list of all the JAR files that are on the build path (as well as their contents), use thePackage Explorer view in the WPF Designer.

Importing JARs

If you want to add your own JAR files to a project, you can put them in a number of places. Theusual place for custom JARs is either in the WebContent/WEB-INF/lib directory or WebCon-tent/WEB-INF/work/lib directory. You can use the WebContent/WEB-INF/lib directory if you donot plan to change your JAR files, or the WebContent/WEB-INF/work/lib directory for any JARfiles that you plan to update regularly (timestamps on JAR files in this directory are automaticallychecked whenever you rebuild the model, so that you can dynamically load in new JARs duringdevelopment). You can also use the WebContent/WEB-INF/clientLibs directory for JAR files thatyou don’t want to add to the server’s classpath (such JARs might already exist on the server andwould only be used at design time).

Page 272: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

WPF JAR files used as part of your IDE are stored in the eclipse/com.bowstreet.designer.core_[WPFversionnumber]/lib directory in your WPF installation. An example of such a fileis the Domino NCSO.jar file, which is used by the Domino Data Access coordinator to fetcha list of views in the builder UI.

To add a new JAR file to your WPF project, first copy the JAR file to the WebContent/WEB-INF/lib directory inside the project. If you were going to be regularly updating the JARfile, you would want to copy it to the WebContent/WEB-INF/work/lib directory instead. JARfiles in these locations are used when your application is deployed. If you copied your JAR froma location on the server (such as the shared/app directory on the portal), you should copy it to theWebContent/WEB-INF/clientLibs directory so that it is not added to the server’s classpath whendeployed.

Open the Project Properties dialog by right-clicking on your project folder and choosingProperties. Switch to the Java Build Path page, and then click on the Libraries tab. Click the AddJARs button to display the JAR Selection dialog, navigate down to where the JAR file is stored,select it, and click OK. Click OK to close the Project Properties dialog, and you should now beable to access the JAR within your application.

Excluding JARs fromWAR Files

WebSphere Portal installations have a shared repository for JAR files, which is located under theshared directory in your portal server’s root directory. If you are using JARs that contain func-tionality used across multiple applications, you might want to consider putting them in this direc-tory. Java methods in your application are then able to access these JARs after they are deployed.

When testing or compiling your applications, however, the portal’s shared directory isunavailable, and you will get errors when you try to compile code that accesses nonexistent JARs.To get around this problem, you can import the JARs into your project (as described in the previ-ous section) but exclude the JAR files from the deployed WAR (so only one copy of the JARs willexist after the application has been deployed). This also reduces the size of your deployableapplication (as opposed to storing JARs in the WebContent/WEB-INF/clientLibs directory,which only prevents them from being added to the server’s classpath).

To exclude a JAR file from the deployable application, first import the JAR file into yourproject as described in the previous section. Then copy the JAR file to the shared/app directory onyour portal server and restart the portal server (your deployed application uses this JAR instead ofthe one currently in your project). After you’ve done this, open the .excludeFromServer file underthe WebContent directory (by default you can’t see this file in the Project Explorer view, but youcan see it by opening the Navigator view). Any entries in this file are excluded from the deploy-able WAR (all entries are relative to the project root folder).

Java Archives 235

Page 273: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Change the contents of the file so that it reads as follows:

# Add any files that you want excluded from the deployed

�server in this file.

# All paths start at the application root. For example:

�WEB-INF/lib/myJar.jar

WEB-INF/lib/testJar.jar

where testJar.jar is the name of your JAR file. Save the contents of the file when you are finished,and deploy your application. To test that your change worked, rebuild your portlet applicationand open the deployable WAR when the process has finished. The specified JAR file should notbe part of the WAR.

TIP

If you have a JAR in your project that already exists in the portal’s shared directory and youwant to use the version in your project rather than the version on the portal server, youneed to configure the application’s classloader policy to ‘Parent last’. (It is ‘Parent first’ bydefault, meaning that the JARs in the portal’s shared directory take precedence.) To do this,open the administration console for the portal server (https://localhost:10039/ibm/consoleby default) and navigate to the Applications/Enterprise Applications page. Locate and clickthe deployed application, select Web modules, and then click on the WAR filename.Change the Class loader mode property to Parent Last, click OK, and then save your changes.

Summary

In this chapter, you learned how to extend your WPF portlet applications with Java. You learnedabout the use of the Method and Linked Java Object builders, as well as how to use JARs and Javabeans. You also learned about some of the APIs that are useful in manipulating WPF applications,particularly in relation to the Domino Java API and the webAppAccess object. Finally, you createda service provider to interact with a collection of Java beans, and a shopping cart model to commu-nicate with this service. The shopping cart model was surfaced to a portal server as a portlet.

Chapter 9 discusses how you can provide and consume Web services in WPF portlets, aswell as how to manipulate XML using a combination of prepackaged builders and the Java IXmlinterface.

Important Points

• You can view a WPF application’s Java code by opening the WebApp Tree tab for a par-ticular model, and then viewing the contents of the Method and Linked Java Objectheadings.

236 Chapter 8 Using Java in Portlets

Page 274: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• Java statements can be used to return the results of Java expressions for inputs in abuilder that accept indirect references (such as the Actions input in the Action Listbuilder), using the following syntax:

${Java/[Java expression]}

where [Java expression] should be replaced with a Java expression that will beevaluated and returned to the builder input (for example: ${Java/webAppAccess.getModelName()}).

• The Method builder enables you to insert Java code inside your WPF applications andshould be used when you want to insert small snippets of Java (particularly those thatare not going to be reused in other models).

• The Linked Java Object (LJO) links to a physical Java class file in your project andmakes the methods of this class available in a model. When implementing Java methodsin WPF, the LJO should be preferred over the Method builder when long methods areused, or if the methods might be reused in more than one model.

• Javadoc for the WPF APIs is available in the WPF Designer Help, under IBM Web-Sphere Portlet Factory Designer, Reference, API documentation.

• To ensure the separation of your data and presentation tiers, Java beans should be madeavailable via a service provider. The Bean Master Detail builder automatically creates aUI to interface with a Java bean, but it mixes data and presentation and should thereforeonly be used for testing purposes.

• In WPF, some builders provide methods to surface further functionality. These methodsare of the following form:

{BuilderCallName}{BuilderMethod}

• Imported JARs can be stored in the WebContent/WEB-INF/lib directory, or under theWebContent/WEB-INF/work/lib directory if you intend to regularly change them.

Important Points 237

Page 275: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 276: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

239

C H A P T E R 9

Using Web Servicesand ManipulatingXML

Web services enable people to consume and provide services over a network. They are commonlyused in distributed applications (that is, applications made up of components sitting in differentruntime environments). When working with Web services in WebSphere Portlet Factory (WPF),as in other environments, XML is often used to communicate between the Web service and theconsumer of the Web service.

This chapter demonstrates how you can use Web services and XML documents in yourWPF applications. By the end of this chapter, you will understand how to create and consumeWeb services in WPF and you will understand some of the methods available in WPF for inter-acting with XML. You will build a stock-ordering application that utilizes a Web service anddemonstrates XML manipulation. This chapter does not cover basic service concepts (such as theservice provider/consumer pattern), as these are discussed in Chapter 2, “Providing and Consum-ing Services.” You don’t necessarily have to read Chapter 2 before you read this chapter, but ifyou are completely new to services, you may find Chapter 2 a more appropriate starting point.

The models discussed in this chapter are available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 9 folder (instructions for copying these files into yourproject are included in a readme.txt file in the same folder); however, to increase your under-standing of using Web services and XML in WPF, it is recommended that you create the modelsyourself by following the example in this chapter.

The following topics are covered in this chapter:

• Web services in WPF

• Creating an order stock Web service

• Creating a service provider

• Creating an order stock portlet

• XML Transform builders

Page 277: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Web Services in WPF

A Web service is a service that is provided and consumed over a network, and there are a numberof builders in WPF you can use to automate the process of creating and consuming these services.WPF applications use standards such as WSDL, SOAP, and XML when working with Web ser-vices, which means that WPF Web services can be provided not only to WPF applications, but toapplications developed in other environments as well (for more information on some of the termi-nology used when discussing Web services, see the “Web Service Terminology” sidebar). UsingWPF, you can also consume Web services developed in other environments, in addition to Webservices developed in WPF.

When providing or accessing Web services in WPF, you should use the service provider/consumer pattern (this pattern is discussed in Chapter 2). The service provider is not a Web ser-vice itself, but acts as an intermediary between the service consumer and any Web services thatare required in order to construct the service provider’s functionality. The provider used in theexample in this chapter, for instance, calls a Web service to execute stock-ordering functions; theOrder Stock portlet accesses these functions from the service provider. Using a service providerin this way enables you to abstract your service implementations from the presentation tier,which means that you can change the mechanics of your service providers (for example, by link-ing them to different Web services) without having to change the service consumers. Serviceproviders also give you a number of testing features (such as service stubs) that you wouldn’t nor-mally have if you just called Web services directly from your service consumers. A diagramdemonstrating the process of consuming Web services through a service provider is shown inFigure 9.1 (note that the Web service in the diagram can be part of a WPF application as well).

240 Chapter 9 Using Web Services and Manipulating XML

WPF Application

ServiceProvider

WebService

ServiceConsumer

Request

Request

Response

Response

Figure 9.1 Web service consumption in WPF.

Page 278: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

WEB SERVICE TERMINOLOGY

A number of standard terms are used when discussing Web services; these are defined inthe following:

XML Namespace—An XML namespace provides a unique context for XML attributes andelements.Two XML elements with the same name but different namespaces are seen as dif-ferent elements.

Schemas—Schemas define the structure of XML documents and are often used in WPF todefine variables, as well as inputs and outputs for services. WPF uses schemas based onthe http://www.w3.org/2001/XMLSchema namespace. Schemas used in Web ser-vices are included in the WSDL for the service, which are then accessible to consumers ofthe service.

SOAP—Simple Object Access Protocol (SOAP) is a standard protocol used to exchangeinformation between Web services. Web services that use SOAP communicate via requestand response messages. In the example, the ID of a stock item and a quantity of it to orderare taken from the user, and assembled into an XML request object. This request object isthen sent to the Web service via a SOAP message. After the Web service has finished pro-cessing the request, it assembles an XML response object and returns it to the consumerthrough another SOAP message.

WSDL—Web Services Description Language (WSDL) is an XML document used todescribe a Web service. Web services that communicate through SOAP usually provide aWSDL, so that consumers of the service know the structure of the requests and responsesused, as well as the operations that the service provides.

In WPF, XML is normally used to structure communication with Web services. This isdone by sending XML request messages to the Web service, which sends back XML responsemessages to the consumer. These XML structures are commonly defined by schemas, which helpto ensure the integrity of the communication. In WPF, a combination of builder calls and Java areused to work with these requests and responses, and WPF provides its own Java interface (calledIXml) to access and manipulate XML.

In this chapter, you build two applications. The first contains a model to be published as aWeb service, which places stock orders in a simple inventory system; the second application con-tains a portlet that consumes the Web service. The stock list is stored in an XML variable insidethe Web service, and XML is also used to communicate with the Web service. The structure ofthis communication (a request object and a response object) is defined by several schemas in theWeb service. The Web service application is deployed to an application server, and the portletapplication is deployed to a portal server.

Web Services in WPF 241

Page 279: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating an Order Stock Web Service

In this section, you build a Web service to provide functionality for ordering stock. The Web ser-vice contains a single operation called orderStock, which takes two inputs: the ID of a stock itemto order and a quantity to order. The operation, when consumed, orders the stock item in thequantity specified. To keep the example simple, an order consists of incrementing a stock counterfor the item ordered by the quantity specified; if the item does not exist in the orders variable,then it is added. After you create the Web service, the next section of this chapter, “Creating aService Provider,” provides the interface between the Web service and the portlet, and then the“Creating an Order Stock Portlet” section walks you through the process of creating a model toconsume the operations in the service (this model is then surfaced to a portal server as a portlet).

Before you begin the steps in this section, you should create a new WPF project, which willhouse the model that provides the functionality for the orders Web service. You should use a newproject even if you already have a project in your workspace from a previous chapter, as this willshow you how to use Web services that are not stored in the same project as your service providerand consumer (you can even run the Web service on a remote server if you have another applica-tion server available). The Web service runs as a standalone application on an application serverrather than as a portlet application, as you don’t need any of the benefits provided by the portletcontainer. You can still run the application as a standalone Web application on the portal server ifit is convenient for you, provided it runs on your local machine; otherwise, it is recommendedyou use the IBM WebSphere Application Server Community Edition server (WAS CE) thatcomes with WPF.

Create the Web Service project, and set up its application server deployment configuration(for more information on this process, see Chapter 1, “Introduction to WebSphere Portlet Fac-tory”). The project will be published as a WAR file and deployed to an application server. Afteryou have a project set up, you need to add a model to the project. This model uses the followingbuilders:

• Service Definition

• Schema (x2)

• Variable (x2)

• Method

• Service Operation

Note that the Service Definition and Method builder calls must both precede the ServiceOperation builder call in your model; if this is not the case, you will get errors indicating thatthere are missing resources.

242 Chapter 9 Using Web Services and Manipulating XML

Page 280: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

In WPF, there are two ways to make a model into a Web service:You can either enable theGenerate WSDL checkbox on a Service Definition builder call or add a Web Service Enablebuilder call to your model. Generally speaking, the best approach is to use the checkbox onthe Service Definition builder, as this builder gives you more facilities for testing the Webservice, and it is quicker and easier to configure than the Web Service Enable builder.

Creating a Model

Create a new model called orderStockWebService in your project, under the folder WEB-INF/models/chapter09. The model should be based on the Empty template, which creates amodel with no builder calls in it. For more information on creating models, see the example inChapter 1.

Defining the Service

The first builder call to add is a Service Definition, which defines a name for your service andpublishes it as a Web service. To do this, select Service Definition from the Builder Palette (youcan open the Builder Palette by clicking the icon in Outline view) and press OK. Change thename of the builder call to orderStockWebService, and then enable the Generate WSDLcheckbox. Finally, expand the Testing Support section and select the checkbox for Add TestingSupport, which enables you to test the service after you have created it. Save the builder call.

TIP

The Service Definition builder automatically uses Document Literal SOAP encoding for ser-vice messages. Document Literal encoding provides the most interoperability with otherWeb services.

Defining the Request Object

Now you need a schema for the XML data that is to be sent to the Web service (known as therequest object). This schema defines the structure of all the inputs to a particular Web serviceoperation, and it is included in the WSDL document that is generated from your Web service (ifthe term WSDL is unfamiliar to you, see the “Web Service Terminology” sidebar at the beginningof this chapter). You don’t need to worry about what this WSDL file consists of as WPF creates itfor you, but you do need to know how to find it (which you will see how to do later in thissection).

Creating an Order Stock Web Service 243

Page 281: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

In the example in this chapter, you create schemas directly, using the Schema builder call.However, you can also get WPF to automatically generate a schema based on the structureof a Variable builder call, by adding a Simple Schema Generator builder call to your model.The Simple Schema Generator is useful if you don’t know how to write XML schemas, but itrequires you to first create Variable builder calls to base the schemas on. An example usingthe Simple Schema Generator is given in Chapter 2.

Add a Schema builder call to the model, then type the name orderStockRequestSchemafor the Schema builder call. Select the ‘Specify explicitly as builder input’ option so that you cantype the schema directly into the builder call. In the Schema Source box, type the followingXML:

<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

xmlns:tns=”http://com.ibm.orderStockRequest”

targetNamespace=”http://com.ibm.orderStockRequest”>

<xsd:element name=”OrderStockRequest”>

<xsd:complexType>

<xsd:sequence>

<xsd:element ref=”tns:ID” minOccurs=”1” maxOccurs=”1” />

<xsd:element ref=”tns:Quantity” minOccurs=”1”

maxOccurs=”1” />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name=”ID” type=”xsd:string” />

<xsd:element name=”Quantity” type=”xsd:int” />

</xsd:schema>

This schema defines the OrderStockRequest object, which is passed into the Web service asa request. The OrderStockRequest element contains two subelements that are used as inputs: anID and a Quantity, which correspond to the ID of the item to be ordered and the quantity to beordered. These elements are referenced inside the <xsd:sequence> element, and are not defineduntil the bottom of the schema. Alternatively, you can define the inputs directly inside the<xsd:sequence> element, but the approach used above is usually easier to read, especially whenyour schemas contain multiple complex types.

244 Chapter 9 Using Web Services and Manipulating XML

Page 282: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Note also the schema definition at the top of the schema; the xmlns:xsd attribute defines anamespace for types prefixed by xsd, and the xmlns:tns defines a namespace for types prefixed bytns. The targetNamespace attribute declares the namespace for all elements defined in the schema(such as ID and Quantity). For more information on the terms namespace and schema, see thesidebar “Web Service Terminology.”

When you are done editing the schema, save the builder call.

Defining the Response Object

Next, you need to add another schema for the XML data that is to be returned from the Web ser-vice (known as the response object). This schema defines the structure of the results that are to bepassed back to callers of the Web service, and it is also included in the WSDL document that isgenerated from your Web service.

Add a Schema builder call to the Web service provider model and name it orderStock-ResponseSchema. Select the ‘Specify explicitly as builder input’ option as you did with the pre-vious schema. In the Schema Source box, type the following XML:

<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

xmlns:tns=”http://com.ibm.orderStockResponse”

targetNamespace=”http://com.ibm.orderStockResponse”>

<xsd:element name=”OrderStockResponse”>

<xsd:complexType>

<xsd:sequence>

<xsd:element ref=”tns:Result” minOccurs=”1”

maxOccurs=”1” />

<xsd:element ref=”tns:Fault” minOccurs=”1”

maxOccurs=”1” />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name=”Result” type=”xsd:string” />

<xsd:element name=”Fault” type=”xsd:string” />

</xsd:schema>

This schema defines the OrderStockResponse object, which is passed back from the Webservice as a response. The OrderStockResponse object contains two subelements that arereturned to the caller of the Web service: Result and Fault. Result holds the results of the orderoperation (how many items are currently on order for the ID specified in the orders variable), andFault holds debugging information if an exception is raised.

Save the builder call when you are finished.

Creating an Order Stock Web Service 245

Page 283: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Order Data

Now add a Variable builder call to the model. The variable created by this builder call holds anXML document containing all of the stock items currently on order. Name the variable ordersand make it of type XML. In the Initial Value field, enter the following XML, which defines threeitems with a quantity of zero:

<StockOrders xmlns=”http://com.ibm.orders”>

<Item>

<ID xmlns=””>00001</ID>

<Quantity xmlns=””>0</Quantity>

</Item>

<Item>

<ID xmlns=””>00002</ID>

<Quantity xmlns=””>0</Quantity>

</Item>

<Item>

<ID xmlns=””>00003</ID>

<Quantity xmlns=””>0</Quantity>

</Item>

</StockOrders>

In the Advanced section of the Variable builder call, select ‘Read-only: shared across allusers’ for the State and Failover input, and then save the builder call. By default, separate vari-ables are created in memory by the Variable builder for each user, so changing this setting ensuresthat only a single orders variable is used across all users. This setting also ensures that the vari-able is stored and recovered if the application fails.

WARNING

The IXml class in WPF is not thread-safe, so, if multiple people are updating an XML vari-able at the same time, be sure your code ensures that only one thread at a time updatesthe variable.

Adding a Method to Place a Stock Order

Add a Method builder call to your model. This builder call contains a Java method to place astock order, which provides the functionality for your Web service orderStock operation. Themethod takes one input (the XML request object), processes the order based on this input, andthen returns one output (the XML response object).

246 Chapter 9 Using Web Services and Manipulating XML

Page 284: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

Because the code in this method is fairly long, it is sometimes placed in a Java source fileinstead of a Method builder call, and then linked to from your model via a Linked JavaObject. This is useful if you like to use the more advanced editing features of your IDE (asthe Method builder itself provides only limited formatting).

Name the builder call orderStock, and then enter one argument called orderStockRe-quest of type IXml, as shown in Figure 9.2 (IXml is a Java interface used to access and manipu-late XML). This enables the method to access the orderStockRequest XML object that is passedinto the function. Change the Return Type as well so that it is IXml.

Creating an Order Stock Web Service 247

Figure 9.2 Configuring the Method builder call.

In the Method Body field of the Method builder call, enter the following Java method (notethat this method is also available for download from ibmpressbooks.com/title/9780137134465under the Chapter 9 folder):

{

try

{

//get id and quantity from request object

String id = orderStockRequest.findElement(“ID”).getText();

Page 285: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

int quantity =

�Integer.parseInt(orderStockRequest.findElement(“Quantity”).getText());

//set the total quantity that is on order for the item specified

//this quantity will be increased if there are already orders for this item

int onOrderTotal = quantity;

//get orders variable and put all the elements from it called ‘item’ into a

//list updating this list will update the orders variable

IXml orders = webAppAccess.getVariables().getXml(“orders”);

List ordersList = orders.getChildren(“Item”);

//flag that denotes whether a stock item already exists

boolean stockAlreadyExists = false;

//check if an order for the specified stock item already exists in the list

for (Iterator it = ordersList.iterator(); it.hasNext();)

{

//get order from orders list

IXml order = (IXml)it.next();

//if there is already an order for the id specified...

if (order.findElement(“ID”).getText().equals(id))

{

//the order already exists, increment quantity in orders variable

IXml quantityItem = order.findElement(“Quantity”);

onOrderTotal = quantity+Integer.parseInt(quantityItem.getText());

quantityItem.setText(Integer.toString(onOrderTotal));

//flag that the item already exists

stockAlreadyExists = true;

//exit for loop

break;

}

}

//if the stock item doesn’t already exist in the orders variable

if (! stockAlreadyExists)

248 Chapter 9 Using Web Services and Manipulating XML

Page 286: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

{

//order doesn’t exist, create new order

IXml newElement = orders.addChildElement(“Item”);

newElement.addChildWithText(“ID”, id);

newElement.addChildWithText(“Quantity”, Integer.toString(quantity)) ;

}

//place order into orders variable

webAppAccess.getVariables().setXml(“orders”, orders);

//assemble response object

String resultString = “An order was successfully made for “ + quantity + “

�items of “ + id + “.<br>” + onOrderTotal + “ items of “ + id + “ are currently

�on order.”;

IXml responseXml = XmlUtil.create(“OrderStockResponse”);

responseXml.addChildWithText(“Result”, resultString);

responseXml.addChildWithText(“Fault”, “”);

//return response object

return responseXml;

}

catch (NumberFormatException e)

{

//an exception was raised, return fault information

IXml errorXml = XmlUtil.create(“OrderStockResponse”);

errorXml.addChildWithText(“Result”, “No result — exception raised.”);

errorXml.addChildWithText(“Fault”, “An invalid quantity was specified.”);

return errorXml;

}

catch (Exception e)

{

//an exception was raised, return fault information

IXml errorXml = XmlUtil.create(“OrderStockResponse”);

errorXml.addChildWithText(“Result”, “No result — exception raised.”);

errorXml.addChildWithText(“Fault”, e.getMessage());

return errorXml;

}

}

Creating an Order Stock Web Service 249

Page 287: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Spend a few minutes going over the method to see how it works. (For information on howXML is manipulated in the code, see the “Using the IXml Interface” sidebar. Also, for informa-tion on the use of the webAppAccess Java object, see Chapter 8, “Using Java in Portlets”). Essen-tially, the method takes the ID and Quantity from the request object (which is passed into theMethod builder call) and cycles through all of the orders in the orders variable to see if there is amatch for the ID specified. If there is a match, then the Quantity specified is added to the Quantityof the matched order in the orders variable; otherwise, a new order is added to the orders variable,with the ID and Quantity specified in the request object. Finally, a response object is created andreturned to the caller of the method, which contains the result of the order operation and any faultinformation. Note also that if an invalid value is specified for the quantity, a NumberFormatEx-ception is raised and the ‘An invalid quantity was specified’ message is returned in the Fault out-put. Any other exceptions are caught and returned as part of the fault output.

Save the Method builder call when you are finished.

USING THE IXML INTERFACE

The IXml interface is used in WPF to create, access, and manipulate XML. It offers numer-ous functions for carrying out common operations on XML documents. The XmlUtil class issometimes used in conjunction with the IXml interface to perform XML manipulation (seeChapter 8 for more examples of using the XmlUtil class).

In the example in this chapter, when the response object is built, the following code isused to create a variable in memory called responseXml, which holds a new XML structurecalled OrderStockResponse:

IXml responseXml = XmlUtil.create(“OrderStockResponse”);

Code using the addChildWithText method, as shown below, is then used to add child ele-ments to this structure:

responseXml.addChildWithText(“Result”, resultString);

The previous code adds an element called Result that contains the value of the resultStringvariable.

The following code is used to set the value of the XML variable created by the ordersVariable builder call:

webAppAccess.getVariables().setXml(“orders”, orders);

The following code is used to retrieve the contents of the variable and store it in an IXmlvariable for further processing (note that any changes to the IXml orders variable alsochange the XML variable orders created by the Variable builder call):

IXml orders = webAppAccess.getVariables().getXml(“orders”);

To get a list of elements in an XML variable, you can use code similar to the following (usedin the example):

List ordersList = orders.getChildren(“Item”);

250 Chapter 9 Using Web Services and Manipulating XML

Page 288: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This gets all of the child elements matching a particular name (Item, in this case). This listcan then be iterated through and processed as in the example.

Additionally, the following code can be used to find the first instance of a particular XMLelement (Quantity) and store it in an IXml variable:

IXml quantityItem = order.findElement(“Quantity”);

You can then use the methods getText() and setText() to get and set the values of these ele-ments, as shown in the two code fragments that follow:

String id = orderStockRequest.findElement(“ID”).getText();

quantityItem.setText(Integer.toString(onOrderTotal));

Adding a Service Operation

Now, add a Service Operation builder call to the model. Use this builder to define an operation forthe Web service; in particular, you declare its request and response objects and what it actuallydoes when it is run (that is, execute the orderStock method). Point the Data Service input to theorderStockWebService Service Definition, and then change the name of the Service Operation toorderStockItem. Specify orderStock for the Action to Call, and type the description Ordersa stock item into the Operation Description input (this description is available to consumersof the operation).

Specify the request object for the operation by expanding the Operation Inputs section, andmaking sure the Input Structure Handling input is set to ‘Specify input schema’. Now, selectorderStockRequestSchema/OrderStockRequest for the Input Schema, and fill out the InputDescription with the text stock item and quantity to order. The Input Field Mapping input shouldbe set to Automatic. This uses the request schema you created earlier to define the structure of therequest object to this operation, and the request inputs passed in will be automatically mappedinto your schema.

TIP

Note that the Service Operation builder enables you to take the structure of your inputs andoutputs from the called action, which is to say that the structure will be taken from theinputs and outputs of the action specified in the Action To Call input.You can’t use thisoption if the action returns an XML variable that is not schema typed, which is the case withthe method used in this example (it is declared as being of type IXml only). Later in thischapter, you set up a service operation that takes its inputs and outputs from the calledaction.

Creating an Order Stock Web Service 251

Page 289: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Specify the response object by expanding the Operation Results section. Select SpecifyResult Schema for the Result Structure Handling input, and then select orderStockResponseSchema/OrderStockResponse for the Result Schema (this is the response schema you createdearlier). Type the description Text describing results of order, and any fault informa-tion if an exception was raised into the Result Description input, and save the builder call whenyou are finished.

TIP

To iterate through an entire XML structure, you may find a recursive function useful. Forexample, the following code iterates through an XML structure passed into it as an argu-ment, and prints the element name and value to the console. The function calls itself toprocess all of the sibling and child elements of each node in the hierarchy. Copy this codeinto a Method builder, rename the builder call to iterateThroughXml, and then add oneargument called xml of type IXml:

{

for(IXml element = xml.getFirstChildElement(); element != null;

�element = element.getNextSiblingElement())

{

System.out.println(“XML element name: “ + element.getName());

System.out.println(“XML element value: “ + element.getText());

iterateThroughXml(webAppAccess, element.getFirstChildElement());

}

}

You have now successfully created a stock-ordering Web service. The next section explainshow you can test the service.

Testing the orderStockWebService Web Service

To test the orderStockWebService Web service from your IDE, run your model from the WPFDesigner by clicking the icon on the toolbar. This runs the currently active model (order-StockWebService) with the last run configuration you used. If you have not set up a run configu-ration before, you are prompted to do so—create a new configuration under the WebSpherePortlet Factory Model category (if you want more information on setting up a run configuration,see the “Testing the Application” section in Chapter 1). A testing interface should display, asshown in Figure 9.3, and it should list the operations in your service.

252 Chapter 9 Using Web Services and Manipulating XML

Page 290: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating an Order Stock Web Service 253

Figure 9.3 Testing your Web service.

To test whether the orderStockItem operation correctly orders a stock item when the itemdoesn’t exist in the orders list, click the orderStockItem link, and an interface for entering inputsinto the operation (as shown in Figure 9.4) is displayed. Type an ID for an item that doesn’t existin the orders XML document (for example, 00004) and a quantity to order (for example, 3), andthen press the Submit Order button. The page reloads and will now contain nothing other than theBack button.

Figure 9.4 Ordering a new stock item.

To test whether the operation works when the stock item does exist in the orders list, clickthe orderStockItem link again and enter the same details as before. When you press the SubmitQuery button, you should see that the quantity for item 00004 has been incremented by theamount specified (3). Press Back when you are finished.

Finally, to test whether exceptions are correctly handled, click the orderStockItem linkagain and leave the inputs blank. Press the Submit Query button and you should see that theresponse returned indicates that an exception was raised (see Figure 9.5).

Figure 9.5 Testing exception handling.

Page 291: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

254 Chapter 9 Using Web Services and Manipulating XML

After you have finished testing the Web service, click the View WSDL link on the test page.You should see a WSDL document similar to that shown in Figure 9.6.

Figure 9.6 Displaying the WSDL for the orderStock service.

This WSDL document will be used in the service provider you create in the next section. Asmentioned earlier, you don’t need to understand how the WSDL works; however, you do need touse the URL for the WSDL and paste it into the service provider (this is covered in the nextsection).

Note that because WSDL and SOAP are commonly used Web service standards, you canuse this Web service not only in WPF, but also in applications developed using environmentsother than WPF. After you run the Web service, it is accessible to all applications (WPF or other-wise) that have access to the application server you deployed the Web service provider applica-tion to.

Page 292: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

The Web service developed in this section is accessed from the development WAR. If youwant to deploy this service to a production environment, you must create a deploymentWAR, install it on an application server, and then run the application. The service is thenaccessible to all users with access to the server and won’t contain any unnecessary devel-opment artifacts included in the development WAR. Note, however, that the URL for theWSDL changes accordingly.

Creating a Service Provider

Now that you have a Web service, you need another WPF project to house the models for theorder stock portlet. Separating the Web service and order stock portlet into two separate projectsmeans that they can be deployed separately, so that the Web service can be run independently ofthe portlet. If you have a project from a previous chapter, you can use it; otherwise, you shouldcreate a new WPF project (for more information on creating projects, see Chapter 1). The projectwill be published as a WAR file and deployed to a portal server, and you should also deploy theapplication to a local application server for testing (as with the previous project, you can use theportal server if it runs on your local machine; otherwise, you should preferably use WAS CE, butyou can also use another application server such as Tomcat or WAS 6.x).

After you have a project set up, you need to add two models to the project (a serviceprovider and a service consumer). The service provider accesses the Web service directly, and theservice consumer then calls this Web service via the service provider. The first model you createis the service provider. It uses the following builders to provide its functionality:

• Service Definition

• Web Service Call

• Service Operation

• Method

Creating a Model and Defining the Service

Create a new model called orderStockService in your project, under the folder WEB-INF/models/chapter09. The model should be based on the Empty template, which creates a modelwith no builder calls in it. After you have added the model to your project, add a Service Defini-tion builder call to the model and name it orderStockService. Enable the Add Testing Sup-port checkbox in the Testing Support section, and save the builder call.

Creating a Service Provider 255

Page 293: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Calling the Web Service

Add a Web Service Call builder call to your model. This builder call is used to consume the oper-ation on the Web service you created earlier in this chapter. Enter the name consumeStockSer-vice for the builder call, and then enter the URL for the WSDL for your Web service into theWSDL URL input (you can obtain this URL by pressing the View WSDL link from the Web ser-vice test page). This URL differs depending on your project name and the server you deployedthe Web service to, but it should be similar to the following:

http://localhost:10038/WebServiceExample/webengine/Chapter09/

orderStockWebService/Action!getWSDL

You should be able to type this URL into a Web browser and see the WSDL document (asshown earlier in Figure 9.6). After you put in the correct URL, you can press the Fetch WSDL but-ton to fill in the Web Service Call builder call with the values from the WSDL. Note that you caneasily consume any WSDL-based Web service simply by specifying the URL for the WSDL in theWSDL URL input. If a WSDL changes, be aware that you will need to refresh the Web Service Callbuilder call (which you can do by pressing the Fetch WSDL button and saving the builder call).

TIP

The Service Call Type input in the Web Service Call builder enables you to connect to anumber of different Web services. WSDL Web services are common and easy to use, butnot all Web services publish WSDL documents (nor are they always made available to you).Aside from WSDL Web services, using WPF can also be used to call SOAP Web servicesthat don’t publish WSDL documents. HTTP Web services can be used as well. Note thatWPF provides a LOCAL option for accessing Web services that exist in the same project asyour consumer, but to make your applications more extensible, it is recommended that youalways use the service provider/consumer pattern when accessing local services.

If you cycle through some of the inputs in the Web Service Call builder call, you can seethat they have been populated with values obtained from the WSDL. Enable the AutoCreate InputVars input in the Request Parameters section, which automatically populates the request objectwith whatever values are sent in to the Web service call. Save the builder call when you arefinished.

TIP

The Service Information section of the Web Service Call builder call lists some basic infor-mation (e.g., descriptions and namespaces) on the Web service, and the Advanced sectionenables you to configure such things as a username and password to use when accessingthe Web service (if one is required).You don’t need to configure any of these inputs in thecurrent example.

256 Chapter 9 Using Web Services and Manipulating XML

Page 294: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Service Operation

The last builder call for the orderStockService defines an operation for the service. Add a ServiceOperation builder call to the model and name it orderStockItem. Set the Data Service to order-StockService, and enter the Action to Call as DataServices/consumeStockService/execute (thisline is used to execute the operation defined in the Web Service Call).

Expand the Operation Inputs and Operation Results sections, and make sure you take eachstructure from the called action. This uses the appropriate schemas from the Web Service Call todefine the structure of the request and response to the orderStockItem service (the same schemasare used). The field mapping in each section should also be set to Automatic. Save the builder callwhen you are finished.

TIP

Although the request and response objects are automatically created in this example, youcan also manually create them using IXml. For example, the following method can be usedto construct a request object to send to the Web service:

{

//assemble request object

IXml requestXml = XmlUtil.create(“OrderStockRequest”);

requestXml.setAttribute(“xmlns”,

�“http://com.ibm.orderStockRequest”);

requestXml.addChildWithText(“ID”,

�webAppAccess.getRequestInputs().getInputValue(“stockItem”));

requestXml.addChildWithText(“Quantity”,

�webAppAccess.getRequestInputs().getInputValue(“stockQuantity”));

//return request object

return requestXml;

}

The service provider is now ready to test.

TIP

If you’re browsing through the Select Action dialog opened from the service provider, youmay notice that the consumeStockService Web service under the Methods section has anumber of methods available, and one of these is the invoke method. When calling an oper-ation on a Web service, you can use either the invoke method or the execute command(like in the example), as they both do the same thing.

Creating a Service Provider 257

Page 295: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Testing the Service Provider

To test the service provider, run it from your IDE. The testing interface is exactly the same as forthe Web service, with the exception that no link is provided to view the WSDL (because the ser-vice provider is not itself a Web service). Step through the same tests for the Web service andmake sure you can access the Web service operation correctly.

If you get any errors when testing the service provider, check that you have correctly con-figured the Web Service Call builder call and that you can access the WSDL document for theWeb service in a browser.

TIP

One of the most common error messages you can get when trying to access a Web serviceis as follows:

The AXIS engine could not find a target service to invoke!

targetService is null

If you get this error, there is likely a mismatch between the structure of your request objectand the request object expected. Check that the structure and namespace of your requestobject match those specified in the schema for the request object in the Web service.

Creating an Order Stock Portlet

Now that your service provider is finished, you need to create a consumer for the service, whichwill be published to a portal server as a portlet. A screenshot of the finished product is shown inFigure 9.10.

The order stock portlet uses the following builders to provide its functionality:

• Action List (x2)

• Page

• Portlet Adapter

• Service Consumer

• Variable

• Data Page (x2)

• Button

Note that the Page builder call should precede the Data Page builder call to improve perfor-mance; this is because the Data Page builder call references the results of the Page builder call,and putting the Page builder call first stops the WPF generation engine from making two passesof the builder calls in your model.

258 Chapter 9 Using Web Services and Manipulating XML

Page 296: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Model

Create a new model called orderStock in your project, under the folder WEB-INF/models/chapter09. The model should be based on the Main and Page template, using a Page Type ofSimple Page. For more information on creating models, see the example in Chapter 1. After themodel is created, it should have two builders in it: an Action List called main and a Page calledpage1. The Action List runs automatically whenever the model is run and will open the page1Page.

Modifying the Page

Open the Page builder, and change the contents of the Page Contents (HTML) input to the HTMLlisted in the following:

<html>

<head><title>Order Stock</title></head>

<body>

<form name=”myForm” method=”post”>

<div align=”center” style=”font:12pt Arial;font-weight:

bold;color: #336699;”>Order Stock</div>

<br>

<span name=”serviceRequest”></span>

<br>

<span name=”submitOrder”></span>

<br>

<br>

<span name=”serviceResponse”></span>

</form>

</body>

</html>

The HTML contains three span tags that replaced later in this section using builders inWPF: The first (serviceRequest) is for the request inputs, the second (submitOrder) is for a buttonto submit the form, and the third (serviceResponse) is for displaying the results of the service.Save the builder call when you are finished.

TIP

There are a number of different ways that you can work with HTML in WPF. You can, as inthe example, use a Page builder; or you can include an external HTML file in the WebCon-tent folder of your project, which you can then use in your model via an Imported Pagebuilder call. You can also combine these methods using the Inserted Page builder to insertpages into other pages.

The use of HTML in WPF is discussed in Chapter 5, “Customizing Portlet Appearance.”

Creating an Order Stock Portlet 259

Page 297: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Portlet Adapter

The first builder call to add is a Portlet Adapter builder call, which surfaces the orderStock modelas a portlet on the portal server specified in your deployment configuration. Add a Portlet Adapterbuilder call to the model, and then change the Name to orderStock. Also, change the PortletTitle to Order Stock and the Portlet Description to Allows users to order stock items.This surfaces your model to the portal server as a portlet called Order Stock. Save the builder callwhen you are finished.

Consuming the Service

Add a Service Consumer builder call to the model. You use this model to make the operations in theorderStockService service available in your model. Change the name of the builder call to order-Stock, and then specify the location of the provider in the Provider Model input (chapter09/orderStockService). Save the builder call when you are finished.

Creating a Variable to Store the Request

Now add a Variable builder call to the model. This builder creates a variable based on the requestschema for the orderStockService service, and is sent to the service when users press the SubmitOrder button in your portlet. Later, you use this variable to build an interface for users to enter IDand Quantity information.

Change the name of the variable to stockRequest, and then select the request schemafrom the service for the Type input (orderStockConsumeStockService_WSDLSchema_1/OrderStockRequest). This automatically populates the Namespace input with the appropriatenamespace taken from the schema. Leave the Initial Value input blank (as the variable will be setby users when they run the application and enter values for the ID and Quantity fields) and savethe builder call.

Displaying the Interface

Add a Data Page builder call to the model (for more information on the use of the Data Pagebuilder, see Chapter 3, “Using Data from a Relational Data Source”). This Data Page is used tobuild an interface so that users can specify values for the order ID and Quantity. Change the nameof the Data Page to displayServiceRequest, and change the Variable input to point to thevariable you created earlier (Variables/stockRequest/OrderStockRequest). Change the Page Typeinput to Data Entry, so that text fields are automatically created for each element in the variable(ID and Quantity). Change the Page in Model input to page1, and the Location for New Tagsinput to serviceRequest, so that the results of the builder are displayed at the serviceRequest tagon page1. Save the builder call when you are finished.

The next step is to add a Data Page builder call to display the results of calling the Web ser-vice. Add a Data Page to the model and name it displayServiceResponse. Select DataSer-vices/orderStock/orderStockItem/results/OrderStockResponse for the Variable input and press

260 Chapter 9 Using Web Services and Manipulating XML

Page 298: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

OK. This makes the Data Page display the results of executing the operation described by theconsumeStockService builder call.

Next, specify page1 for the Page in Model input, so that the results are displayed on thepage created by the Page builder you created earlier, and specify ‘View Only’ for the Page Type(because there is no need to be able to edit the results). In the Created Element Settings section,specify serviceResponse in the Location for New Tags input, so that the results are displayed atthe serviceResponse <span> tag, and then save the builder call.

Adding Submit Functionality

Next, add an Action List builder call. This action list is run whenever the user submits an order bypressing the Submit Order button, and it contains three actions: first, it sets the request object forthe orderStockItem operation from the OrderStockRequest variable (which contains the ID andQuantity values entered by the user); then it executes the orderStockItem operation; and finally, itdisplays the page created by the Page builder call (which then displays the results of calling theservice on the screen).

For the first action, use the Select Action dialog (which you open by pressing the ellipsisbutton to the right of the row you want to change), and select Assignment from under the Specialsection. Fill out the Make Assignment dialog that follows, as shown in Figure 9.7, and press OKto accept the action.

Creating an Order Stock Portlet 261

Figure 9.7 Configuring the Make Assignment dialog.

For the second action, select the orderStockItem operation (DataServices/orderStock/orderStockItem), and type page1 for the third action. Save the builder call when you are finished.

The last builder call to add is a Button builder call. This inserts a button at the submitOrder<span> tag on the HTML page, and it enables users to submit a stock order (by calling the ActionList you created earlier, which calls the Web service and displays the results on the page). Add aButton builder call and configure it as shown in Figure 9.8. Save the builder call when you arefinished.

The service consumer is now ready to test.

Page 299: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

262 Chapter 9 Using Web Services and Manipulating XML

Figure 9.8 Configuring the Submit Order button.

Testing the Order Stock Portlet

To test the orderStock model, run it from your IDE. The page shown in Figure 9.9 should displayin your default Web browser. The functionality of the service consumer is the same as the serviceprovider, so step through the same three tests for the service consumer.

Figure 9.9 Interface for the service consumer.

After you have tested your model, you should rebuild the application containing the portletand test it on the portal server as a portlet (for instructions on how to do this, see the example inChapter 1). After you have added the portlet to a page in the portal, your portlet should display asshown in Figure 9.10.

Page 300: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

XMLTransform Builders 263

Figure 9.10 The Order Stock portlet.

XMLTransform Builders

You have already seen how to create, access, and manipulate XML using the IXml interface,which gives you control over your XML processing. However, WPF also comes with a number ofbuilders to perform several common XML transformations, which are discussed in the followingsections. These builders don’t give you as much control as the IXml interface, but they can beimplemented without writing any Java code (although it is also possible to extend them with cus-tom Java transformation methods).

Transform

This builder can be used to copy a source XML document into a target XML document. You usethis builder if you want to modify the structure of an XML document from one schema to another.To use this builder, both the source and target XML documents must be defined by a schema.

The example in the next chapter uses this builder to copy an XML element into a structurewhere it can be rendered as a chart via the Web Charts builder.

Transform - Filter

This builder can be used to filter elements in and out of an XML document or Java bean. The fil-tered XML can be saved over the top of the old XML document or into a new XML document.Note that although some of the other XML builders also enable basic element level filtering, theTransform - Filter builder enables you to specify detailed filter expressions based on variablevalues. So, for example, you can filter all elements with a name that does not equal a certain vari-able value.

Page 301: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

264 Chapter 9 Using Web Services and Manipulating XML

Transform - Rename

This builder renames a particular element in an XML document, and then saves the results basedon a particular schema (it doesn’t necessarily have to be the same as the original schema). Thetarget XML of the builder does not have to be the same as the source XML.

Transform - Sort

This builder enables you to sort an XML document or Java Bean collection, based on a particularelement name. The XML document must be based on a schema to be used by this builder. Thesource and target XML do not necessarily have to be the same, but they need to be based on thesame XML schema.

An example using XML transformation is provided in Chapter 10, “Using Charts inPortlets.”

Summary

In this chapter, you learned how to create a Web service and consume it from WPF. You alsolearned how to store, access, and manipulate XML documents using WPF features, such as theIXml interface, the Variable builder, Schema builder, and the Transform builders. You also cre-ated, deployed, and tested two applications: a Web service providing an operation to order stockitems and a portlet application to enable users to order stock items via the Web service.

The examples in this chapter can be extended not just to providing and consuming otherWeb services from within WPF, but to providing Web services to applications developed outsideof WPF, and consuming publicly available Web services as well (which could have been devel-oped in any number of different languages). A list of publicly available Web services can befound at www.xmethods.org.

Chapter 10 discusses how to create charts in a portlet using WPF.

Important Points

• Web services can be implemented in WPF using the service provider/consumer pattern.Web services built in WPF can be accessed both inside and outside of WPF applications.Applications built outside of WPF can access WPF Web services.

• A model can be converted into a Web service by adding a Web Service Enable builder,or by enabling the Generate WSDL option on the Service Definition builder.

• A model can call a Web service using the Web Service Call builder. Web services shouldbe called from a service provider.

• XML documents are often used in WPF for Web service communication and are usuallysent via SOAP messages. Consumers send a request message to the Web service, whichthen returns an appropriate response.

Page 302: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• The IXml interface is a powerful way to create, access, and manipulate XML documentsin WPF.

• The Transform builders can be used to transform one XML document into another,without writing any Java code.

• The Schema builder can be used to define an XML schema for Web service requests andresponses.

Important Points 265

Page 303: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 304: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

267

C H A P T E R 1 0

Using Charts inPortlets

Graphical charts are an impressive, visually appealing way to present information, and Web-Sphere Portlet Factory (WPF) provides the capability to automatically render a variety of chartsinside your portlets. This chapter focuses on how to use the charting capabilities of WPF, and bythe end of the chapter, you will have a good knowledge of the different chart configurationoptions available. To demonstrate these techniques, you will build a portlet that displays salesinformation, which you can then use to experiment with the different chart styles available. Thisportlet also enables users to drill down in the chart to get more information on a particular chartitem.

The example application discussed in this chapter utilizes one model and one XML styledefinition, which are available for download from ibmpressbooks.com/title/9780137134465,under the Chapter 10 folder (instructions for copying these files into your project are included ina readme.txt file in the same folder). However, to increase your understanding of the topics dis-cussed in this chapter, it is recommended that you create these files yourself by following theexample.

The following topics are covered in this chapter:

• Charting data in WPF

• Creating a service provider

• Creating a sales chart portlet

• Adding drill-down capabilities

• Custom chart styles

• Upgrading to a deployment license

Page 305: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Charting Data in WPF

The Web Charts builder enables you to quickly and easily add charting capabilities to yourportlets in WPF, based on the contents of an XML data set. You can create an XML data set inWPF by using one of the data access builders (such as Domino Data Access or SQL DataSource),which automatically create XML data sets based on data taken from a particular data source. Youcan also explicitly specify XML data sets in Variable builders or XML files; the example in thischapter demonstrates this approach.

A number of different chart styles are available when using the Web Charts builder,which are:

268 Chapter 10 Using Charts in Portlets

• Area

• Bar

• Dial

• Line

• Pyramid

• Pie

• Radar

• Step

You can also add custom styles to a chart by importing XML style definition files into yourproject, which you can create using a program called Web Charts 3D (available online fromwww.gpoint.com). Web Charts 3D gives you a graphical interface for selecting and customizingchart styles, and it lets you change chart colors, format chart text, and add effects to charts (such asshadows and translucency). An example of using a custom style is provided later in this chapter.

TIP

The Web Charts builder included with WPF is an evaluation version only. There is no expi-ration date on the evaluation period; however, an evaluation version message is displayedat the bottom of each chart until you obtain a deployment license.You can obtain a deploy-ment license by contacting GreenPoint at [email protected]. The “Upgrading to a Deploy-ment License” section in this chapter describes how to upgrade the Web Charts builderafter you obtain a license.

The Web Charts builder also provides drill-down capabilities; that is, the facility to activatesections of a chart so that users can click on them to bring up more information. Given that chartsare easier to understand if they display only a small amount of data, this provides a convenientway to show detailed information on points of interest in your charts. For example, in this chap-ter, you will see how to add drill-down functionality to a chart displaying quarterly sales figures.When a user clicks on one of the bars in the chart (corresponding to a month in the last financialyear), a pie chart is opened, displaying a breakdown of sales figures by sales area for that month.

Developers can extend the capabilities of the Web Charts builder using the WebSphereDashboard Framework. The Dashboard Framework is an extension to WPF, which provides(among other things) additional builders that offer new charting functionality. For example, theBullet Graph builder provides a wizard-based interface for creating charts that measure perfor-mance against a goal, and the Map builder enables you to create color-coded maps of particular

Page 306: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

geographical locations, which users can drill down into for more information. The DashboardFramework also aggregates several common charting functions in WPF into higher-levelbuilders; for example, the Summary and Drilldown builder can be used to quickly add page tabs(usually added by the Page Tabs builder) to navigate between a chart and its drill-down informa-tion (both of which are usually added by the Web Charts builder).

The next section walks you through the process of creating a chart portlet in WPF. Thechart displays monthly sales figures taken from a service provider model, which is built in thenext section. For more information on the service provider/consumer pattern, see Chapter 2,“Providing and Consuming Services.”

Creating a Service Provider

Before you can use the charting capabilities of WPF, you need a WPF project to hold the chartportlet. If you have a project from a previous chapter, you can use it, but you will need to add theGreenPoint Web Chart Builder feature set (to do this, open the Project Properties dialog andselect GreenPoint Web Chart Builder from under the Charting category in the WebSphere PortletFactory Project Properties/Feature Info section). If you don’t have an existing project, create anew WPF project with the GreenPoint Web Chart Builder feature set enabled (for more informa-tion on creating projects, see Chapter 1, “Introduction to WebSphere Portlet Factory”). Theproject will be published as a WAR file and deployed to a portal server, and you should alsodeploy the application to a local application server for testing (you can use the portal server if itruns on your local machine; otherwise, it is recommended you use the IBM WebSphere Applica-tion Server Community Edition server [WAS CE] that comes with WPF).

In this section, you build a service provider model to make sales data available to the saleschart portlet. The following builders provide the model’s functionality:

• Service Definition

• Variable

• Simple Schema Generator

• Action List

• Service Operation

Note that the Service Definition builder call must come before the Service Operationbuilder call, and the Service Operation builder call must follow the Action List (otherwise, youwill get errors that indicate that these resources are unavailable). Similarly, the Simple SchemaGenerator must follow the Variable builder call.

Creating a Model

Create a new model called salesService in your project, under the folder WEB-INF/models/chapter10. Because you will be storing your data in an XML variable rather than getting it from adatabase, you need to create the service provider manually. To do this, the model should be based

Creating a Service Provider 269

Page 307: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

on the Empty template, which creates a model with no builder calls in it (for more information oncreating models, see the example in Chapter 1).

Defining the Service

Add a Service Definition builder call by selecting Service Definition from the Builder Palette(you can open the Builder Palette by clicking the icon in Outline view) and pressing OK.Name the Service Definition salesService, and then enable the Add Testing Support checkboxin the Advanced section. This lets you run the model and test whether your service operation isworking correctly. Save the builder call when you are finished.

Adding Sales Data

The next step is to add an XML document to the model, which defines the sales data displayed inthe chart. Add a Variable builder call to the model and call it sales. Change the Type input toXML, and then type the following XML document into the Initial Value input:

<Sales>

<Item>

<Month>January</Month>

<Area1>113630</Area1>

<Area2>134980</Area2>

<Area3>253340</Area3>

<Area4>182100</Area4>

<TotalSales>684050</TotalSales>

<TargetSales>630000</TargetSales>

</Item>

<Item>

<Month>February</Month>

<Area1>109990</Area1>

<Area2>147330</Area2>

<Area3>224320</Area3>

<Area4>208650</Area4>

<TotalSales>690290</TotalSales>

<TargetSales>650000</TargetSales>

</Item>

<Item>

<Month>March</Month>

<Area1>142270</Area1>

<Area2>155740</Area2>

270 Chapter 10 Using Charts in Portlets

Page 308: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

<Area3>197630</Area3>

<Area4>212740</Area4>

<TotalSales>708380</TotalSales>

<TargetSales>700000</TargetSales>

</Item>

</Sales>

WPF charts can graphically represent any XML document, provided that it is possible tomeaningfully split up the document into rows and columns. In the previous XML, each Item ele-ment corresponds to a separate row, which contains a set of columns. In this section, the Monthand TotalSales columns are used to display data on the chart for each row.

Save the builder call when you are finished.

Adding a Sales Schema

The next builder call to add is a Simple Schema Generator, which automatically creates an XMLschema for you. This schema is used by the service to define the structure of the sales data itreturns to service consumers.

Add a Simple Schema Generator builder call to your model and name it salesSchema.For the Sample Data input, specify the Variable you created in the previous step (sales), and thenspecify the URI in the Target Namespace section as http://wpf.ibm.com/2002/10/sales.Save the builder call when you are finished.

Adding an Action to Retrieve Sales Data

Now add an Action List builder call to the model and name it getSales. This action list returnsthe contents of the sales variable you created earlier and is called from the Service Operationbuilder call created next (you need to create the action list first; otherwise, you will get errors inyour project, indicating missing resources). Change the Return Type of the builder call to IXml.IXml is a WPF interface used to manipulate XML and is used because there is no XML data typeWPF as such. For more information on the IXml interface see Chapter 9, “Using Web Servicesand Manipulating XML.” Open the Select Action dialog for the first action in the Actions input(you can do this by pressing the ellipsis button to the right of the first row in the Actions input).From the Select Action dialog, select Special/Return to return a value to the caller of the ActionList, then select the Sales element in the sales variable (Variables/sales/Sales). Press OK to acceptthe action, and save the builder call when you’ve finished.

Specifying the getSales Operation

The final builder call to add to the service provider is a Service Operation. Add the Service Oper-ation builder call now and name it getSales. Point the Data Service input to the Service Defini-tion builder call created earlier (salesService) and specify the Action To Call as getSales (this isthe action list you just created).

Creating a Service Provider 271

Page 309: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

You now need to specify the inputs and outputs for the Service Operation. To do this,expand the Operation Inputs section and select ‘No inputs’ for the Input Structure Handling input(because no inputs are required, the operation just needs to return sales data). For the OperationResults section, select ‘Specify result schema’ for the Result Structure Handling, which lets youspecify the schema of your results, and then select the Sales element of the salesSchema schemafor the Result Schema input (salesSchema/Sales). Make sure the Result Field Mapping input isset to Automatic. This specifies the structure of the results returned from the operation. Make surethat the results from the getSales action are automatically mapped into this schema.

Your service provider is now ready to test.

Testing the Service Provider

Because you have opted to add testing support in the Service Definition builder call, WPF auto-matically generates test pages for your service provider (which you can disable from the ServiceDefinition builder call). This enables you to test the service provider directly from the IDE.

To test the service, run the salesService model from the WPF Designer by clicking the icon on the toolbar. This runs the currently active model (salesService) with the last run configu-ration you used. If you have not set up a run configuration before, you are prompted to do so—create a new configuration under the WebSphere Portlet Factory Model category (if you wantmore information on setting up a run configuration, see the “Testing the Application” section inChapter 1).

You should now see the index test page in your default Web browser, as shown in Figure10.1. This screen displays a link to test the getSales operation on the salesService service.

272 Chapter 10 Using Charts in Portlets

Figure 10.1 Index test page from the salesService model.

To test the getSales operation, click the getSales link. You should see some sales data, asshown in Figure 10.2. Press Back to return to the index page.

Your service provider is now complete.

Figure 10.2 Testing the getSales operation.

Page 310: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Sales Chart Portlet

In this section, you add a chart portlet to your WPF project to display quarterly sales figures for afictional company. The total sales figures for each month display in bars along the x axis of thechart. The data used in the example is retrieved from an XML document stored inside the portlet,although you can use XML produced by any of the WPF builders (as well as imported XMLfiles). A screenshot of the model output from this section is given in Figure 10.7 toward the end ofthis chapter.

The “Adding Drill-Down Capabilities” section later in this chapter extends the portlet byenabling users to display a pie chart of sales figures by sales area for a particular month. In the“Custom Chart Styles” section of this chapter, you also add a horizontal line to the chart reflect-ing target sales for each period.

The following builders are used in this section:

• Portlet Adapter

• Page

• Action List

• Service Consumer

• Web Charts

Creating a Model

To add a chart model to the project, create a new model called salesChart in your project,under the folder WEB-INF/models/chapter10. The model should be based on the Main and Pagetemplate, using a Page Type of Simple Page. For more information on creating models, see theexample in Chapter 1. After it is created, your model should have two builders in it: an Action Listcalled main and a Page called page1. The Action List runs automatically whenever the model isrun and opens the page1 Page.

Modifying the Page

Now open the Page builder and replace the contents of the Page Contents (HTML) input with thefollowing HTML:

<html>

<body>

<div align=”center”>

<span name=”salesChart”></span>

</div>

</body>

</html>

The chart you create in this chapter is placed at the salesChart span tag. Note that it is easierto share your HTML with other developers or between projects if use HTML files rather than the

Creating a Sales Chart Portlet 273

Page 311: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Page builder; you can then reference these pages via the Imported Page builder. In this example,the Page builder is preferred because it is a fairly simple HTML page that is not intended to bereused in other portlets.

Save the builder call when you are finished.

Modifying the Main Action List

The main Action List defines the execution flow for the salesChart model. In this example, theexecution logic is simple: You run the getSales operation, and then display the contents of page1.To do this, open the main action list. You can see that an action already exists to open page1, socreate a new action by opening the Select Action dialog for the second action in the Actions input.Add an action to consume the getSales operation, as shown in Figure 10.3.

274 Chapter 10 Using Charts in Portlets

Figure 10.3 Consuming the getSales operation.

Press OK to accept this action. When control returns to the Action List builder, drag anddrop the page1 action so that it occurs after the action you just created (you don’t want to displaypage1 until the getSales operation has executed). Save the builder call when you are finished.

Adding a Portlet Adapter

You can now add a Portlet Adapter, which surfaces your model as a portlet when the applicationis deployed to a portal server. Select Portlet Adapter from the Builder Palette and press OK.Name the Portlet Adapter salesChart, and then change the Portlet Title to Sales Chart andthe Portlet Description to This portlet displays a chart containing sales infor-mation. This surfaces the sales model as a portlet called Sales Chart. Save the builder call whenyou are finished.

Page 312: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Consuming the Service

Next, add a Service Consumer builder call to the model to consume the salesService serviceprovider you created in the previous section. Name the Service Consumer sales, and point theProvider Model input to chapter10/salesService. Save the builder call.

Adding a Chart

The final builder call to add to the salesChart model in this section is a Web Charts builder call,which displays the TotalSales values from the sales Variable in a bar chart. Add a Web Chartsbuilder call to the model and name it salesChart, and then fill out the Page Location section ofthe builder call, as shown in Figure 10.4. This replaces the contents of the salesChart span tag onthe page1 page with a chart defined by the Web Charts builder call.

Creating a Sales Chart Portlet 275

Figure 10.4 Configuring the page location for the sales chart.

The next section of the builder, Chart Style and Data, defines the data set for the chart andhow the chart is formatted. For the Chart Data input, open the Choose Reference dialog (by click-ing the ellipsis button to the right of the input) and select the Sales element of the results from thegetSales operation, as shown in Figure 10.5.

Figure 10.5 Specifying the Chart Data input.

Page 313: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This setting links the chart to the Sales element of the results returned from the getSalesoperation. Note that if you want to chart a sequence of values (as you normally do), then you needto point the Chart Data input to an element that contains a sequence of rows. For example, theSales element contains a sequence of Item elements, so it is used as the target for the Chart Datainput. If you try to link directly to the sequenced elements (Item, in this case), then only the firstelement in the sequence is charted.

Make sure Bar is selected as the Chart Type, which outputs the results of the Web Chartsbuilder as a bar chart. When you test your portlet in the next section, you can also experimentwith some of the other available styles.

Configuring the Data Transformation

The next section of the builder call, Data Transformation, defines how the data set is read to dis-play it in the chart and whether any transformations need to be performed before the data isdisplayed (the original data set is not affected). Make sure Tabular Data (Rowset/Row) is set forthe Data Source Format input; this transforms the sales data into a format readable by the WebCharts builder. When using this option, note that your data needs to be in a similar structure tothat used in the example; that is, in a row set containing a sequence of rows, where each row con-tains one or more columns, as shown in the following (data returned from the data access buildersis already in this format):

<RowSet>

<Row>

<Column1>Value1</Column1>

<Column2>Value2</Column2>

</Row>

<Row>

<Column1>Value3</Column1>

<Column2>Value4</Column2>

</Row>

</RowSet>

TIP

You can also select the WebCharts Format option for the Data Source Format input, whichdoes not perform any transformation on the data set. When you use the WebCharts Formatoption, the rows and columns in the data set must be defined in the following way:

<XML>

<COL>ColumnName1</COL>

<COL>ColumnName2</COL>

<ROW COL0=”NumericValue1” COL1=”NumericValue2”>Series1</ROW>

276 Chapter 10 Using Charts in Portlets

Page 314: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

<ROW COL0=”NumericValue3” COL1=”NumericValue4”>Series2</ROW>

</XML>

Each column name is defined in a COL element, and the column values are specified inROW elements. The order of the column elements defines how they display in the chart.When specifying column values inside the ROW element, each COL reference must alsohave an index that relates the column value back to one of the columns defined by the COLelements. Note that the enclosing element must be called XML (case sensitive) and thatrow and column elements must be called ROW and COL, respectively (also case sensi-tive). Note also that the numeric values in each column are contained in quotes.

Because you are using the Tabular Data (Rowset/Row) format, you need to define whichparts of the data set should be used in the chart (this is not required when using the WebChartsFormat option). Type Month for the X Axis Tag input, which defines the values for the x axis ofthe chart in terms of the Month element (so each bar on the chart is labeled with a different Monthvalue).

Next, specify ‘Include columns’ for the Include or Exclude Columns input, so that you canchoose the elements that display as bars in your bar chart (that is, the values for the y axis). A newinput called Column List displays immediately below the Include or Exclude Columns input;select TotalSales for the first column (you will add other columns later in the chapter).

Specifying Chart Properties

The Chart Properties section of the builder enables you to configure various aspects of the chart’sappearance. By default, these settings come from the underlying chart style. Because you are dis-playing only one column for each month (TotalSales), you don’t need a legend for the chart, sochange the Show Chart Legend input to No Legend. When you add additional columns later inthis chapter, you will revert this back to its default setting. You do not need to change any of theother default chart property settings at this point.

Skip over the Chart Click Action section—you return to this section later in the chapterwhen you add drill-down capabilities to the chart.

Specifying Minimum Scale Values

By default, the origin of the bar chart (that is, the point where the x and y axes meet) will be atcoordinate {0,0}. This is fine in most circumstances, but because the y values in the currentexample (TotalSales) are so large, the difference between each month is not easy to discern. Tomake the chart easier to read, you should change the y axis so that it begins at point 600,000rather than at point 0. This makes the differences between each month stand out more, withoutexcluding any of the chart values (assuming, of course, that no value ever drops below 600,000).When you test the model in the next section, you can revert the y axis back to the default setting,which makes the effect of modifying the y axis setting clearer.

Creating a Sales Chart Portlet 277

Page 315: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The Data Labels section specifies settings for placing data labels on the page. Leave thedefault settings in the Data Labels section, which uses the label settings specified by the chartstyle, and save the builder call.

You now have a model displaying a chart of sales information, which you will test in thenext section.

Testing the Test Data Portlet

To test the chart portlet, first run the chart model from the WPF Designer. After you have run thesalesChart model, you should see a chart displaying sales figures for a three-month period, asshown in Figure 10.6. Hover over each of the bars on the chart, and you should see the total salesfigures for each month displayed.

278 Chapter 10 Using Charts in Portlets

Figure 10.6 Testing the salesChart model.

Experiment with some of the other chart styles available by opening the Web Charts buildercall, modifying the value of the Chart Type input, and then retesting the model. The “CustomChart Styles” section in this chapter discusses how you can modify the appearance of the defaultstyles. You can also try to reverse the minimum value of the y axis back to the default setting,which demonstrates how you can modify the appearance of the chart by changing the axissettings.

After you have tested the salesChart model, you should rebuild your application on the por-tal server (for instructions on how to do this, see the example in Chapter 1), after which you willbe able to view the salesChart model as a portlet on the portal server. After you have added thesalesChart portlet to a page in the portal, it should appear as shown in Figure 10.7.

The next section of this chapter discusses how to add drill-down capabilities to the portlet,so that you can get more information about a particular chart item.

Page 316: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Drill-Down Capabilities 279

Figure 10.7 The salesChart portlet.

Adding Drill-Down Capabilities

In this section, you create a drill-down page for the salesChart model, which displays sales infor-mation by area in a pie chart. When a user clicks on a particular bar in the bar chart (correspon-ding to a particular month), he is taken to the sales area information for that month. Of course,you can use any page for the drill-down page, and you don’t necessarily need to display anotherchart (a table, for example, is a common way to display detailed information for a chart drill-down).

The following builders are added in this section:

• Comment (x2)

• Variable (x2)

• Transform

• Action List (x2)

• Service Operation

• Page

• Web Charts

• Button

TIP

The WebSphere Portlet Factory Dashboard Framework comes with builders that automatemuch of the process involved in adding drill-down functionalities.

Page 317: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Temporary Variables

The drill-down chart displays the current row of the salesChart chart, which can be accessed fromthe rowData property of the Web Charts builder. Because the current row is a subset of the<Sales> element, it is in the following form:

<Item>

<Month></Month>

<Area1></Area1>

<Area2></Area2>

<Area3></Area3>

<Area4></Area4>

<TotalSales></TotalSales>

<TargetSales></TargetSales>

</Item>

As it is, this data cannot be properly rendered in a chart, as it is not enclosed inside aRowset element (such as Sales). One way to get around this is to transform the rowData XML sothat it is enclosed inside a rowset. To transform the rowData XML, you need two temporaryvariables: The first holds the rowData XML before the transformation, and the second holds atransformed version of the XML. Both variables need to be based on a schema to use them withthe Transform builder, which is used to perform the actual transformation (see Chapter 9 for moreinformation on XML transformation).

The transformation should be made to the service provider rather than the service con-sumer (this makes testing easier and it makes it easier to reuse the functionality elsewhere), soopen the salesService model. Add a Comment builder call, name the Comment Sales AreaChart, and then save the builder call. This comment will provide a clear divide in your modelbetween the builder calls for each chart.

Now, add a Variable builder call to the salesService model. Name the builder callcurrentRow, and change the Type of the variable to salesSchema/Item (the item element in theschema), which automatically fills in the namespace of the Variable for you. This builder callholds the value of the current row. Save the builder call when you are finished.

Add another Variable builder call to the model and name it currentRowTransformed.Change the type of the variable to salesSchema/Sales. This builder call will hold the value of thetransformed row. Notice that the root element of the variable is a rowset (Sales); this enables thevariable to be rendered by the Web Charts builder in a chart. Save the builder call when you arefinished.

Defining the Transform

The next step is to define the XML transformation itself. Add a Transform builder call to themodel and name it transformCurrentRow. The Transform builder requires two variables: asource variable, which contains the untransformed XML (currentRow in this case), and a target

280 Chapter 10 Using Charts in Portlets

Page 318: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

variable, containing the transformed XML (currentRowTransformed). Fill out the top section ofthe builder call, as shown in Figure 10.8. This defines the deepest element of the currentRow vari-able (Item) and the deepest element of the currentRowTransformed variable (Sales/Item).

Adding Drill-Down Capabilities 281

Figure 10.8 Configuring parent elements for the Transform builder.

The Child Node Mappings section of the builder defines the mappings between the sourceand target XML documents. Both XML structures use the same element names, as they are basedon the same schema, so there is no need to change any of the default mappings.

Scroll down to the Parent Node mapping input, which defines the mapping of elements thatare higher in the XML document structure than the elements specified in the Child Node Map-pings section. In this case, you have to map only the Item element (you cannot map the Sales ele-ment, as it has no equivalent in the currentRow variable). Configure the Parent Node mappingsection of the builder, as shown in Figure 10.9 (you can delete rows by right-clicking them andselecting ‘Delete row’. Note that you cannot change the value of the source node attribute, so youshould delete the row that contains the blank source node value). Save the builder call when youare finished.

Figure 10.9 Configuring parent node mapping for the Transform builder.

Page 319: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Specifying aMethod to Get the Current Sales Item

The next step is to create a Method that can used to retrieve a particular sales item from the salesVariable, based on the user’s selection. To do this, add a Method builder call to the model andname it getRow. Add an argument of String called index in the Arguments section of the buildercall, and then enter the following code in the Method Body input:

{

//set index

int iteratorIndex = 0;

//get sales Variable

IXml sales = webAppAccess.getVariables().getXml(“sales”);

List salesList = sales.getChildren(“Item”);

//find current row

for (Iterator it = salesList.iterator(); it.hasNext();)

{

//get sales item from sales list

IXml item = (IXml)it.next();

//if current item matches index...

if (index.equals(Integer.toString(iteratorIndex)))

{

try

{

//set currentRow variable

webAppAccess.getVariables().setXml(“currentRow”,

�XmlUtil.parseXml(item.toString()));

}

catch (java.io.IOException e)

{

//set currentRow variable to null

webAppAccess.getVariables().setXml(“currentRow”,

�null);

}

//exit for loop

break;

}

//increment search index

282 Chapter 10 Using Charts in Portlets

Page 320: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

iteratorIndex ++;

}

}

This code iterates through the items in the sales variable and checks to see whether theindex of the item matches the index passed in to the method. If there is a match, the currentRowVariable is set using a String representation of the current item (if an error occurs with the currentRow Variable set to a null value).

Save the builder call when you are finished.

Specifying an Action for the getSalesArea Operation

Now, you need to specify the sequence of actions that will be run when the getSalesArea opera-tion is run. Add an Action List builder call to the model and name it getSalesArea. Add anargument of type String called index, and then change the Return Type of the builder call toIXml (you will be returning an IXml object to the caller of the service operation). Finally, specifythe actions for the Actions input that are shown in Figure 10.10.

Adding Drill-Down Capabilities 283

Figure 10.10 Specifying getSalesArea actions.

The first action runs the getRow Method, passing in the index from the Action List as anargument. The getRow Method then sets the value of the currentRow Variable based on the index.The second action, transformCurrentRowCallCopy, runs the Transform builder’s Call Copy oper-ation, which transforms the currentRow Variable and stores the result in the currentRowTrans-formed Variable. The final action then returns the Sales element of the transformed Variable.

Save the builder call when you are finished.

Specifying the getSalesArea Operation

The final configuration for the service provider is to specify an operation to run the getSalesAreaAction List. To do this, add a Service Operation builder call to the model. Name the ServiceOperation getSalesArea, and specify the Data Service as salesService. For the Action to Callinput, specify getSalesArea.

You now need to specify inputs and outputs for the operation. To do this, expand the Opera-tion Inputs section and select ‘Use structure from called action’ for the Input Structure Handlinginput and make sure the Result Field Mapping input is set to Automatic. This takes the structure of

Page 321: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

the inputs from the inputs of the getSalesArea Action List and automatically maps inputs to the ser-vice operation into this structure. For the Operation Results section, select ‘Specify result schema’for the Result Structure Handling, which lets you specify the schema of your results, and thenselect the Sales element of the salesSchema schema for the Result Schema input (salesSchema/Sales). Make sure the Result Field Mapping input is set to Automatic. This specifies the structure ofthe results returned from the operation. Be sure the results from the getSalesArea action are auto-matically mapped into this schema.

Save the builder call when you are finished. This completes the configuration of the serviceprovider.

Testing the getSalesArea Operation

You should run a quick test of the service provider model at this point. Run the salesServicemodel from your IDE and click on the getSalesArea link from the index test page. Whenprompted, enter an index—0, 1, or 2. You should see a one row table showing sales informationfor a particular month. For example, the results for index 1 (February) are shown in Figure 10.11.

284 Chapter 10 Using Charts in Portlets

Figure 10.11 Testing the transform in the service provider.

Adding a Page for the Sales Area Chart

You now need to configure the salesChart model to display the results of the transform. To dothis, first open the salesChart model and add a Comment builder call to it. Name the CommentSales Area Chart and save the builder call. This comment provides a clear divide in yourmodel between the builder calls for each chart.

Add a Page builder call to the model and name it salesAreaPage. This builder calldefines the HTML that contains the drill-down chart. Type the following HTML into the PageContents (HTML) input:

<html>

<body>

<div align=”center”>

<span name=”salesAreaChart”></span>

<br>

<span name=”backButton”></span>

</div>

</body>

</html>

Page 322: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Drill-Down Capabilities 285

Note the two span tags on the page: The salesAreaChart tag displays the chart, and thebackButton tag displays a Back button to enable users to return to the first chart. Save the buildercall when you are finished.

Adding an Action to Display the salesAreaPage

Next, add an Action List builder call to the model and name it displaySalesAreaPage. Thisaction list defines the actions taken when a user clicks on a bar in the first chart. Add an argumentcalled index of type String to the Arguments section, so that the action list can receive the indexof the selected area of the salesChart chart, and then add three actions to the Actions input, asshown in Figure 10.12. The first action sets the index argument of the getSalesArea operationusing the index passed in the Action List, and the second action then runs the operation. The finalaction displays the salesAreaPage, which shows the transformed XML in a pie chart.

Figure 10.12 Adding actions to the displaySalesAreaPage action list.

Save the builder call when you are finished.

Configuring the Click Action

Open the Web Charts builder for the first chart, and then enable the Enable Click Action option inthe Chart Click Action section. Several other inputs now display, enabling you to configure anaction to be taken when a bar on the chart is clicked. Type the name of the Action List you just cre-ated into the Method to Call input (displaySalesAreaPage), and specify a single argument inthe Inputs input. Call the argument index, and set the value as ${ChartValues/colIndex},which you can type directly or select from under the ChartValues category in the Choose Refer-ence dialog. This calls the displaySalesAreaPage action list, passing in the column index for thecurrently selected row (0 for January, 1 for February, and 2 for March). Save the builder call whenyou are finished.

When you click on a bar in the bar chart, the salesAreaPage is loaded; however, the page iscurrently empty. You now need to add some builders to populate the salesAreaPage page.

Populating the salesAreaPage Page

Add another Web Charts builder call to the model, and name it salesAreaChart. Set the PageLocation section of the builder, as shown below in Figure 10.13.

Page 323: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

286 Chapter 10 Using Charts in Portlets

Figure 10.13 Configuring the page location for the drill-down chart.

Select Pie for the Chart Type input in the Chart Style and Data section, and then select thedata set for the Chart Data input, as shown in Figure 10.14. This creates a pie chart based on theSales element of the results from the getSalesArea operation.

Figure 10.14 Selecting the data set for the Chart Data input.

Fill out the Data Transformation section of the builder call, as shown in Figure 10.15.Notice that no X Axis Tag has been defined; this causes each pie segment to simply display therelevant column values (which, in this case, are the sales figures for each sales area). Save thebuilder call when you are finished.

Next, add a Button builder call to the model to create a Back button at the backButton tagon the salesAreaPage page. Name the builder call backButton, and then fill out the Page Loca-tion section of the builder, as shown in Figure 10.16.

Specify Back for the Label input, and then type page1 in the Action input (this reloads thefirst page). Be sure to also change the Action Type input from ‘Submit form and invoke action’ to‘Link to an action’, as the salesAreaPage has no form. Save the builder call when you are finished.

Page 324: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Drill-Down Capabilities 287

Figure 10.15 Configuring the data transformation for the drill-down chart.

Figure 10.16 Configuring the page location for the Back button.

Testing the Drill-Down from the salesChart Model

You have now added drill-down capabilities to your sales chart portlet. If you test the model fromyour IDE, you should be able to click on a chart bar and see sales area information for any givenmonth. For example, if you click the total sales bar for January, you should see the drill-downchart shown in Figure 10.17. Hovering your cursor over a particular pie chart segment should dis-play the total sales for that sales area in the given month.

Note that you don’t need to rebuild the application to see the changes on the portal server; ifyou have enabled automatic synchronization for the portlet WAR (in the WebSphere Portlet Fac-tory Project Properties section of the Project Properties dialog), you should automatically seeyour changes on the portal when you save your model (although if you are logged in to the portalwhen the synchronization occurs, you need to log out and log back in before you can see thechanges).

Page 325: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 10.17 Testing the sales chart drill-down functionality.

CustomChart Styles

When you specify a value for the Chart Type input in the Web Charts builder, you link your chartto an XML file in your project that contains various parameters that describe the style and type ofthe chart. For example, the bar and pie charts used in this chapter are defined by the Bar.xml andPie.xml files, respectively, which can be found in the WEB-INF/factory/samples/WebChartsdirectory in your project. By default, the chart parameters in the file corresponding to your charttype are used by the Web Charts builder whenever the setting ‘Use chart style’ is selected for aninput, but you can also override the default chart settings with different values. Alternatively, youcan also create your own custom XML chart styles, which is the subject of this section.

TIP

The WEB-INF/factory/samples/WebCharts directory also contains files with a .wcp exten-sion, which are WebCharts Project files. These files can be opened in the WebChartsDesigner tool, which is a graphical interface for modifying and creating the XML style filesused by the Web Charts builder.You can also modify and create your own XML style filesmanually, although this requires that you are familiar with the syntax used by theWebCharts style files.

In this section, you create another series for the bar chart, to display the TargetSales foreach month. You then add a custom style file to your project. The custom style changes the barcolor to a pastel blue and specifies that the target sales should be drawn as a red horizontal line

288 Chapter 10 Using Charts in Portlets

Page 326: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

across the chart. Note that you do not need the WebCharts Designer tool to complete this section,but it is recommended that you download the tool to avoid having to type chart styles manually inthe future.

Displaying TargetSales

To add the new series for TargetSales and create the new chart style, first open the salesChart WebCharts builder call and navigate to the Data Transformation section. Add the TargetSales columnto the Column List input and save the builder call. This displays values for TargetSales and theTotalSales already displayed on the chart.

Because you specified Bar as the chart style, the TargetSales is displayed as additional barson the chart. To display the TargetSales as a line instead of a series of bars (while still displayingthe TotalSales in bar form), you need to create a custom style. To do this, create a new XML fileby selecting New, Other from the File menu, and then select File from under the General cate-gory. Select the WEB-INF/factory/samples/WebCharts directory, and then type the name of thefile as BarAndLine.xml and press Finish. The new XML file opens in the Editor window.

Type the following XML into the BarAndLine.xml file, and then save the file:

<?xml version=”1.0” encoding=”UTF-8”?>

<frameChart is3D=”false”>

<elements outline=”black” drawShadow=”true”

showMarkers=”false”>

<series index=”0” shape=”Bar”>

<paint color=”#00688B”/>

</series>

<series index=”1” shape=”Line”>

<paint color=”red”/>

</series>

</elements>

</frameChart>

This file achieves a number of things. First, it turns off the 3D effect of the chart (is3D=“false”), which makes the chart easier to read with both lines and bars on the chart. Then, itdefines charts for two data series: a blue bar chart and a red line chart. Note that the blue for thebar chart is specified in hexadecimal; you can get hexadecimal codes from the WebCharts 3DDesigner. Each series has a number of effects applied to it: namely, a black outline, a shadowaround each bar or line, and no markers to delineate each individual value. Also, the labels foreach x axis element are now printed horizontally instead of on a slant (because there is no<labelStyle orientation=“Slanted”/> element as there is in the bar.xml file).

CustomChart Styles 289

Page 327: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

It is recommended you use the Web Charts 3D Designer to create your chart styles, as thisenables you to configure your styles visually and then lets the Designer automatically createthe XML style files for you. However, there are a few commonly used style settings that canbe easily and quickly inserted into the XML style files, which are listed in the following:

<title font=”Arial-14-bold” />

This line can be used to modify the font and font size used on chart labels (size 14, Arial fontis used in the previous example).

<paint paint=”Plain” />

This line can be used to turn off the color gradient on chart segments.

<yAxis scaleMin=”0” scaleMax=”100” />

This line can be used to set a minimum and maximum for the y axis (0 and 100 are used inthe previous example).

The following attributes can be added to the elements element to modify chart attributes:

shapeSize=”80”

This attribute can be used to modify the width of bars on bar charts (80 is the default).

lineWidth=”3”

This attribute can be used to modify the width of the line on line charts (3 is the default).

place=”Stacked”

This attribute can be used to place two bars in a bar chart on top of each other, rather thanside by side.

shape=”Column”

This attribute turns a bar chart on its side, displaying horizontal bars instead of vertical bars(note that if you use this setting, you need to define a separate ‘elements’ element to con-tain the line portion of your chart, as you cannot apply the shape=“Column” attribute to aline chart).

Using the Custom Style

The next step is to link the salesChart chart to the new custom style. To do this, open the sales-Chart Web Charts builder call, and then enable the Provide Custom Style checkbox in the ChartStyle and Data section. In the Style Data input that displays, type /WEB-INF/factory/samples/WebCharts/BarAndLine.xml. Also, change the Show Chart Legend input in theChart Properties section to Use Chart Style, which causes the chart legend settings to be takenfrom the chart style (you haven’t defined a chart legend in the chart style, so a legend is displayedby default). Save the builder call when you are finished.

You have now added a custom style to the salesChart chart in the salesChart portlet. Testthe model from your IDE now, and you should see the output shown in Figure 10.18. Note that

290 Chapter 10 Using Charts in Portlets

Page 328: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

you do not need to rebuild the application to see the changes on the portal server (provided thatyou have enabled automatic synchronization for the portlet WAR).

CustomChart Styles 291

Figure 10.18 Testing the sales chart drill-down functionality.

Upgrading to a Deployment License

After you have obtained a deployment license for the Web Charts builder from GreenPoint, youneed to configure your WPF projects to use the new license key. You can upgrade your WPFproject template so that all future projects use the deployment license; however, if you have anyexisting WPF projects, they need to be upgraded separately.

To upgrade a particular WPF project, switch to the Package Explorer view in the WPFdesigner. Directly under the project folder, you will see links to the JAR files contained in theWebContent/WEB-INF/lib directory of your project. Make a copy of the wc50.jar file and paste itto a temporary location (such as the Windows desktop).

TIP

By default, the wc50.jar file does not display under the WebContent/WEB-INF/lib directory inthe Project Explorer view, as the Project Explorer does not display JAR files that are on thebuild path. Use the Package Explorer when browsing archives on the build path.

Note that you can view the contents of archives from the Package Explorer, but youneed to open or copy the archives elsewhere to be able to edit them.

Page 329: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

292 Chapter 10 Using Charts in Portlets

Open the wc50.jar file using a decompression utility and extract the webcharts3d.xml fileto a temporary directory, and then open the webcharts3d.xml file and search for the text license.This should reveal the following attribute:

license=”null”

Type the new license key in place of the text null, and then save the webcharts3d.xml file.Using a compression utility, add the modified webcharts3d.xml file back to the root folder of thewc50.jar archive, and then copy the modified archive back into your project. If you do not intendto upgrade any more projects, you should restart the application server or portal server that yourWPF project(s) are deployed to.

To upgrade the project template so that future WPF projects use the deployment license,copy a modified version of the wc50.jar file (that is, one with a valid license key) into the<WPFinstallDirectory>/FeatureSets/WEB-APP_<version-number>/Templates/Project/wpf.war/WEB-INF/lib directory. When you run your WPF chart portlets, they will no longer display theevaluation version message.

Summary

In this chapter, you learned how to add charts to your portlets and how to customize the appearanceof these charts using a combination of prepackaged and custom chart styles. You also learned howto add drill-down functionality to your charts to provide detailed information on particular chartsegments, and you created a simple WPF portlet application to demonstrate these techniques.

Chapter 11, “Field Validation, Formatting, and Translation,” discusses how to use a combi-nation of out-of-the-box builders and Java methods to customize the way form fields areprocessed in WPF.

Important Points

• Charting capabilities can be added to a portlet using the Web Charts builder. The WebCharts builder that comes with WPF is an evaluation version only; you need to obtain adeployment license from GreenPoint (www.gpoint.com) to use the full version.

• The Web Charts builder offers drill-down functionality that enables users to drill downon sections of your chart to get more information.

• You can create custom styles for your charts using a program called Web Charts 3D.This program creates XML style definition files that you can then import into your WPFprojects and reference from the Web Charts builder.

• The WebSphere Dashboard Framework is an extension to WPF, which offers (amongother things) a number of builders that have new charting functionality and that aggre-gate the functionalities of other lower-level builders.

• When upgrading the Web Charts builder to a deployment license, you need to copy thelicense key into the webcharts3d.xml file and save it into the root folder of the wc50.jarfile in the WebContent/WEB-INF/lib directory.

Page 330: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

293

C H A P T E R 1 1

Field Validation,Formatting, andTranslation

This chapter walks you through the process of adding field-level validation, formatting, andtranslation to portlets. Several different techniques are discussed, including the use of out-of-the-box builders, Java methods, regular expressions, resource bundles, and data definitions. By theend of this chapter, you will have a good understanding of each approach and be able to imple-ment each one in the appropriate scenarios.

The example application discussed in this chapter utilizes one model, a properties file and aJava source file, which are available for download from ibmpressbooks.com/title/9780137134465, under the Chapter 11 folder (instructions for copying these files into yourproject are included in a readme.txt file in the same folder). However, to increase your under-standing of the topics discussed in this chapter, it is recommended that you create the files your-self by following the example.

The following topics are covered in this chapter:

• Validating, translating, and formatting fields

• Creating a projects portlet

• Writing a Formatter class

• Further validation customizations

Validating, Translating, and Formatting Fields

Most portlets that provide information in fields benefit from some validation, translation, and for-matting before they are saved or displayed to users. Validation, for example, can help ensure dataintegrity in backend data sources, whereas formatting can present potentially confusing data in away that end users can more easily understand. Translation, on the other hand, can be used as akind of formatting in reverse—that is, it converts screen inputs into a format more readily used by

Page 331: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

applications or data sources. For example, you might use formatting to display a reference codeas a particular product name, so that it can be understood by people using the system; you mightthen translate this sentence back to a code after it is submitted as part of a form, so that it can beeconomically stored in a database. WPF provides several different techniques for validating, for-matting, and translating fields—the subjects of this chapter. Some of these techniques are brieflyintroduced in the following sections, and the example demonstrates their uses in the propercontext.

Schema Typed and Non-Schema Typed Fields

If you work with fields defined by a schema in WPF, you should look to the Rich Data Definitionbuilder as your first point of reference. The Rich Data Definition enables you to define commonvalidation, translation, and formatting settings for schema typed variables, and specifies moreadvanced settings through the use of various expressions. For example, specifying OptionalDate(yyyy-MM-dd) for a field’s validate expression ensures that if that field has a value, it mustbe formatted as a four-digit year, two-digit month, and two-digit day (in that order). There are anumber of preset expressions available, or you can create your own; you can also use regularexpressions when you need more control over the specific patterns used in a given field.

After you have entered your field validation, formatting, and translation settings using theRich Data Definition builder, you can save your configuration in XML files called data definitionsso that they can be easily reused. Rich Data Definitions also have an input to link to a propertiesfile called a resource bundle, which modifies the messages displayed to a particular user or groupafter validation occurs. The example in this chapter utilizes a data definition and a resourcebundle to customize settings for fields on a data entry form.

If your fields are not schema typed, you should look at applying validation, translation, andformatting through the Data Field Modifier builder, which enables you to modify one or morefields on a form through the same sort of expressions used in the Rich Data Definition builder. Thebuilder you use generally depends on whether your fields are defined by a schema; however, it ispossible to use both builders for the same data set. A Data Field Modifier can be used to overridesettings in your Rich Data Definition, which is useful if you want to apply expressions to manyfields at once (the Rich Data Definition requires that expressions are defined on a per-field basis).

TIP

When using schema typed fields, you can also use the schema itself for limited validation.As a best practice, you should keep schema validation to a minimum and define as muchas possible of your validation using Rich Data Definition or Data Field Modifier builders.

In addition to the Data Field Modifier and Rich Data Definition builders, a data displaybuilder such as the Data Page builder or View & Form builder is usually employed to display your

294 Chapter 11 Field Validation, Formatting, and Translation

Page 332: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

data fields to end users. The Data Page also provides a number of features for validating, translat-ing, and formatting fields that aren’t available from the other builders, such as specifying thelocation of validation messages on a page.

Formatter Classes

Both the Data Field Modifier and Rich Data Definition builder use something called a formatterclass to provide functionality for the different formatting, validating, and translating of expres-sions, and a class called StandardFormatter is used to support the default expressions available. Itis also possible to create your own formatter class if you want to further customize what you cando with the Data Field Modifier and Rich Data Definition builders, however the StandardFormat-ter should be preferred wherever possible because you can use it without writing any Java code.However, creating your own formatter class can be useful if you have requirements that eithercannot be covered or are too complicated to cover with the default expressions in the Standard-Formatter. The example in this chapter shows you how to create a custom formatter class to cus-tomize a phone number field on a project form.

Client-Side and Server-Side Validation

When validating fields, you have another decision to make in addition to choosing which builderyou will use for validation. That is, you have to decide whether you want to use client-side orserver-side validation. Client-side validation reduces the load on the server and can speed up yourapplications; however, there is only so much that can be validated without having to check infor-mation via the server (in a backend data source, for example). The Rich Data Definition and DataField Modifier builders are normally used for server-side validation, and JavaScript is used forclient-side validation. You can use the Dynamic Validation builder to dynamically display valida-tion messages for server-side validation.

TIP

Although it is possible to add JavaScript validation to your applications (by inserting itdirectly into HTML pages or using the Client JavaScript builder), it is not advisable that youdo this unless the other methods available do not fit your specific validation requirements.JavaScript validation routines are usually more difficult to maintain than the other validationmethods in WPF and can be problematic in applications that are used with different Webbrowsers.

The remainder of this chapter focuses on demonstrating these techniques in a sample appli-cation. The sample application provides a portlet containing a form for storing information aboutprojects.

Validating, Translating, and Formatting Fields 295

Page 333: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Projects Portlet

In this section, you build a portlet to provide functionality for entering details for new projects(such as start dates and budgets). Project data entered by the user is stored in a schema typed vari-able inside the portlet. A screenshot of the interface is shown later in Figure 11.7.

Before you proceed with this section, you need a WPF project to house the portlet. If youhave a project from a previous chapter, you can use it; otherwise, you should create a new WPFproject (for more information on creating projects, see Chapter 1, “Introduction to WebSpherePortlet Factory”). The project will be published as a WAR file and deployed to a portal server, andyou should also deploy the application to a local application server for testing (you can use theportal server if it runs on your local machine; otherwise, it is recommended that you use the IBMWebSphere Application Server Community Edition server [WAS CE] that comes with WPF).

After you have a WPF project set up, you can add the model for the project’s portlet. Thefollowing builders are added in this section:

• Portlet Adapter

• Action List

• Comment (x3)

• Page (x2)

• Schema

• Variable

• Data Page (x2)

• Button

• Link

• Text

• Rich Data Definition

• Dynamic Validation

Note that the order of some of these builder calls is important: the Rich Data Definitionshould follow the Schema, the Data Page should follow the Page, and the Dynamic Validationbuilder call should follow the Data Page. If any of these elements are not in order, you willreceive a message in the Problems view indicating the unavailability of resources.

Creating a Model

Create a new model called projects in your project, under the folder WEB-INF/models/chap-ter11. The model should be based on the Main and Page template, using a Page Type of SimplePage. For more information on creating models, see the example in Chapter 1. After it is created,your model should have two builders in it: an Action List called main and a Page called page1.The Action List runs automatically whenever the model is run and opens the page1 Page.

296 Chapter 11 Field Validation, Formatting, and Translation

Page 334: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Modifying the Page

Open the Page builder, which is used to define the layout of the project form itself. Replacethe contents of the Page Contents (HTML) input with the following HTML, and then save thebuilder call:

<html>

<body>

<form name=”projectForm” method=”post”>

<div align=”center” style=”font:12pt Arial;font-weight:

bold;color: #336699;”>New Project Form</div>

<br>

<br>

<span name=”fullError” style=”color:#FF0000;”></span>

<br>

<br>

<span name =”dataEntry”></span>

<br>

<span name=”submitButton”></span>

</form>

</body>

</html>

Notice that the Page contains a form with four main sections. The first section is the head-ing for the form, and the second section (fullError) defines a location for validation messages toappear (this will be written to through the Data Page builder later in the chapter). The third sec-tion is for the data entry form itself (also placed by the Data Page builder), and the final section(submitButton) is for a button control to submit the form.

Adding a Portlet Adapter

The first builder call to add is a Portlet Adapter, which surfaces your model as a portlet when theapplication is deployed to a portal server. Select Portlet Adapter from the Builder Palette (you canopen the Builder Palette by clicking the icon in Outline view) and pressing OK. Name thePortlet Adapter projects, and then change the Portlet Title to Project Form and the PortletDescription to This portlet displays a form for filling out project details.This surfaces the model as a portlet called Project Form. Save the builder call when you arefinished.

Organizing Builders for page1

Add a Comment builder call to the model and name it page1. This comment makes it easier todistinguish the parts of your model that pertain to the first page in the model. Note that two pagesare used in this model: The first is the project form, and the second is a results page displayedwhen the project form is submitted.

Creating a Projects Portlet 297

Page 335: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Save the builder call so that it displays in Outline view, and then drag it so that it displaysabove the page1 builder call. Also, drag the Portlet Adapter builder to the top of the model, andsave the model when you are finished.

The next few builder calls contain functionality for the first page in the model.

Adding a Schema

The next step is to add a schema to define the structure of the project form data. Specifying aschema for your data enables you to define validation, translation, and formatting using a RichData Definition builder (which you add to the model later).

Add a Schema builder call, and then name it dataEntrySchema. Select ‘Specify Explic-itly as Builder Input’ for the Schema Source Type input, and then enter the XML schema shownin the following code into the Schema Source input. Save the builder call when you are finished.

<xsd:schema xmlns:xsd=”http://www.w3.org/2001/XMLSchema”

xmlns:tns=”http://wpf.ibm.com/2002/10/dataEntrySchema”

targetNamespace=”http://wpf.ibm.com/2002/10/dataEntrySchema”>

<xsd:element name=”Items”>

<xsd:complexType>

<xsd:sequence>

<xsd:element ref=”tns:ProjectCode” minOccurs=”1” maxOccurs=”1” />

<xsd:element ref=”tns:ProjectManager” minOccurs=”1” maxOccurs=”1” />

<xsd:element ref=”tns:ProjectManagerContactNo” minOccurs=”1”

maxOccurs=”1” />

<xsd:element ref=”tns:ProjectStartDate” minOccurs=”1” maxOccurs=”1” />

<xsd:element ref=”tns:ProjectEndDate” minOccurs=”1” maxOccurs=”1” />

<xsd:element ref=”tns:ProjectBudget” minOccurs=”1” maxOccurs=”1” />

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name=”ProjectCode” type=”xsd:string” />

<xsd:element name=”ProjectManager” type=”xsd:string” />

<xsd:element name=”ProjectManagerContactNo” type=”xsd:string” />

<xsd:element name=”ProjectStartDate” type=”xsd:string” />

<xsd:element name=”ProjectEndDate” type=”xsd:string” />

<xsd:element name=”ProjectBudget” type=”xsd:string” />

</xsd:schema>

298 Chapter 11 Field Validation, Formatting, and Translation

Page 336: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Variable to Hold User Input

Next, add a Variable builder call to the model. This builder call creates a variable to hold valuesentered by users and is based on the schema created in the previous step. Change the name of thevariable to dataEntry, and then select dataEntrySchema/Items for the Type input. The Name-space input should be automatically populated with the namespace specified in the schema. Savethe builder call.

Modifying the Main Action List

Now that you have created both the page and variable that you need to access, you should modifythe actions in the main Action List so that it performs two actions: First, it clears the contents ofthe variable used to store the values for each field, and then it opens the first page in the model.

To do this, open the main Action List, and notice that there is already an action to openpage1, the first page in the model. Press the ellipsis button next to the second action in the ActionList to create a new action. In the dialog that follows, select Assignment from under the Specialheading and press OK. In the Target field, select Variables/dataEntry; this is the name of the vari-able used to hold the current project data. Leave the Source field blank and press OK. When con-trol returns to the Action List, click and drag the page1 action so that it occurs after the action youjust created, and then save the builder call.

Creating a Form

The next step is to create a form for the project fields so that users can edit them. To do this, add aData Page builder call to the model and name it dataEntry. Change the Variable input to pointto the variable you created earlier (Variables/dataEntry), and then specify page1 as the Page inModel input. Select Data Entry as the Page Type, and then specify dataEntry in the Location forNew Tags input. This creates a form of editable fields at the dataEntry tag on page1, using thedataEntry variable. Save the builder call when you are finished.

Adding a Submit Button

Add a Button builder call to the model and name it submitButton. This button is used to submituser values for the project form. Specify page1 and submitButton as the Page and Tag, respec-tively, in the Page Location section, and then change the Label input to Submit. Make sure theAction Type input is set to ‘Submit Form and Invoke Action.’ This places a button at the submit-Button tag on page1 that submits the form with the user’s values. The Action input should openthe confirmation page, but because the page hasn’t been created yet, just leave this input blank fornow and save the builder call.

You have finished adding all of the builder calls for page1. The next few steps walk youthrough the process of creating a second page to confirm to the user that the entries in the projectform were submitted.

Creating a Projects Portlet 299

Page 337: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding a Confirmation Page

Add a Comment builder call to the model and change the name to page2. Save the builder call.This builder call separates the builder calls in your model so that it is easier to see which buildercalls are related to page1 and which are related to page2.

Now add another Page builder call to the model. Change the name of the builder call topage2, and then enter the following HTML into the Page Contents (HTML) input:

<html>

<body>

<div align=”center”><div style=”font:12pt Arial;

font-weight: bold;color: #336699;”>Project Submitted</div>

<br>

Project form submitted.

<br>

<br>

Results (displayed values):

<br>

<span name=”results”></span>

<br>

<br>

Results (translated values):

<br>

<span name=”translatedResults”></span>

<br>

<br>

<span name=”back”></span>

</body>

</html>

Notice that this page has a tag called results on it—this is where another Data Page willshow the user’s inputs in the display format (as specified by any formatting formulas). The trans-latedResults tag displays the results in the translated form (that is, as specified by any translatingformulas). A Back button will be placed at the back tag so that users can enter details for morethan one project. Save the builder call.

Modifying the Submit Button

Now that you have a page to use for your confirmation page, open the submitButton builder callagain and change the Action input to page2. Save the builder call when you are finished. The Sub-mit button now displays the confirmation page when clicked.

300 Chapter 11 Field Validation, Formatting, and Translation

Page 338: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Displaying the User’s Inputs

Add a Data Page builder call to the model to display the result of the user’s submitted inputs inthe display format (that is, with any relevant formatting formulas applied). Change the name ofthe builder call to displayResults, and then select the Items element of the dataEntry variablefor the Variable input (you can do this through the ellipsis button to the right of the Variableinput). Specify page2 as the Page in Model, and then change the Page Type to View Only so thatusers are not able to change form values after they have been translated and submitted. Finally,specify results for the Location for New Tags input and save the builder call.

Now add a Text builder call to the model, which you can use to display the translated ver-sions of the user’s inputs to the screen. Name the builder call translatedDataEntry, and thenspecify the Page and Tag in the Page Location as page2 and translatedResults, respectively. Forthe Text input, open up the Choose Reference dialog and select the Java/<replace with Javaexpression> option, as shown in Figure 11.1.

Creating a Projects Portlet 301

Figure 11.1 Specifying text for the Text builder.

Press OK, and then specify the Java expression as follows:

webAppAccess.getVariables().getXml(“dataEntry”).toString()

This gets the internal value of the dataEntry Variable (with any translating formulasapplied) and displays it as a string. Press OK to accept the Text input value, and save the buildercall when you are finished.

Adding a Link to Return to the Project Form

The final builder call to add in this section is a Link builder call. This builder call provides a linkthat executes the main Action List when clicked; effectively, this resets all of the form values anddisplays the project form again to the user. Add the Link builder call and name the builder call

Page 339: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

backLink. Change the Page input to page2 and the Tag input to back. Type Return to theproject form for the Link Text input, and then change the Action Type input to ‘Link to anaction’ (there is no need to submit a form because page2 doesn’t contain a form to submit).Change the Action to main and save the builder call.

Running a Preliminary Test

At this point, you should test the model to see how it runs without any custom validation, format-ting, or translation. To do this, first run the chart model from the WPF Designer by clicking the

icon on the toolbar. This runs the currently active model (for instance, projects) with the lastrun configuration you used. If you have not set up a run configuration before, you are prompted todo so—create a new configuration under the WebSphere Portlet Factory Model category (if youwant more information on setting up a run configuration, see the “Testing the Application” sec-tion in Chapter 1).

After you have run the projects model, you should see a form with a series of data entryfields, as shown in Figure 11.2.

302 Chapter 11 Field Validation, Formatting, and Translation

Figure 11.2 Testing the projects model.

Enter some test values and press the Submit button. Notice that there are no restrictions onwhat you can type into each field and that when you submit the form, none of the submitted valuesare translated—that is, they are submitted in exactly the same format as you typed them. Afteryou’ve submitted the form, you should see a results page similar to that shown in Figure 11.3.

Notice that all of the fields on the project form have a red asterisk next to them, which is thedefault character in WPF for denoting mandatory fields. These validation constraints are placedon each field by your XML schema, but they won’t actually prevent the confirmation page fromdisplaying (however, if you leave a field blank, submit the form, and then press the Back button toreturn to the project form, you will see a validation message display for that field). In the next sec-tion, you add some validation, formatting, and translation formulas to the fields on this page, and

Page 340: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

you also see how to prevent users from submitting the form when a field does not pass its valida-tion formula.

Creating a Projects Portlet 303

Figure 11.3 Testing the results page.

Adding Formatting, Validation, and Translation

The next step is to define some validation, translation, and formatting expressions for the fieldson the project form. Before you continue, add another Comment builder call to the model andname it VTF. This comment makes it easier to distinguish the VTF-specific (validation, transla-tion, and formatting) builders used in this section. Save the builder call when you are finished.

Setting Data Page Validation

Before you add any VTF-specific builders, first open the dataEntry builder call, and then scrolldown to the Required Field and Input Validation Settings section. This section contains inputsthat specify how validation is performed on the form. By default, the Validate From Schema inputspecifies that validation information for required fields and data types should be taken from theschema (although this is overridden with any validation specified by the Rich Data Definition).This section also lets you specify what happens after the values in the Data Page are submitted. Itis possible to run an action after the validation has finished, and actions can also be run in theevent of a successful or failed validation process. At this point, you will not use a post-saveaction; however, you do need a success action to display a results page after the project form hasbeen submitted. Change the Success Action input to page2 to open the page2 Page whenever thevalidation succeeds.

Page 341: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

By default, validation messages display next to the field that they pertain to, but it is alsopossible to add a block of text to the HTML that lists all of the errors together. To make this blockdisplay, enter fullError for the Full Error Location input. This inserts the error block at thefullError tag on page1. Save the builder call when you are finished.

TIP

You can prevent individual validation messages from displaying next to each field by remov-ing the following tag from your HTML template:

<span name=”FieldValidationError” class=”ValidationErrorText” />

Modifying the Submit Button

Now open the submitButton builder call, and for the Action input, select page1_NextActioninstead of page2. This method is automatically created by the Data Page builder when you spec-ify post-validation actions, and selecting this method for the button simply kicks off the methodwhen the button is pushed (and after the form has been submitted). The method itself simply dis-plays page1 if any errors are picked up when the form is submitted; otherwise, it displays page2.Save the builder call when you are finished configuring the Button builder call.

TIP

You can view the contents of the page1_NextAction method by navigating to theWebApp/Method section of the WebApp Tree tab in the Model Editor and scrolling down tothe entry for page1_NextAction. There is also an entry in this section for page1_SaveData,which performs the validation. Later in this chapter, you see how you can add post savelogic to this method to gain a greater degree of control over the validation process.

Adding a Rich Data Definition

Now add a Rich Data Definition builder call to the model, and point the Schema input to thedataEntrySchema schema. You should see a list of fields display in the Fields area of the DataDefinition Editor section, as shown in Figure 11.4.

Notice the value of the Base Data Definition File input. This input points to an XML file inyour project that holds settings and expressions used by the Rich Data Definition.

304 Chapter 11 Field Validation, Formatting, and Translation

Page 342: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Projects Portlet 305

Figure 11.4 Fields in the Rich Data Definition.

TIP

After you have finished modifying the Rich Data Definition, you can save your changes to anew data definition file by pressing the Create Data Definition button in the Save SampleData Definition File section.You can then use these data definitions to populate settings inother Rich Data Definition builder calls by modifying the value of the Base Data DefinitionFile input in the Rich Data Definition builder to point to the new data definition.You can pre-view a data definition file in the Advanced section of the Rich Data Definition builder, andyou can also manually edit data definition files with an XML editor.

Select the ProjectCode field, and notice that WPF populates some of the settings on theright of the Fields box with validation, translation, and formatting settings. In the next few steps,you modify some of these settings for each of the fields on the project form.

Modifying Field Settings

First, select each field and modify the Label input so that words in field labels are separated byspaces (so, for example, ‘ProjectCode’ should be changed to Project Code). This makes thelabels that display next to each field a little easier to read. By default, each field has the Requiredcheckbox enabled and a Data Type of string. The Required checkbox causes fields to be validatedwhen a user attempts to save the project form, and if any of the fields are blank, a validation erroris raised and an error message is displayed to the user. Note that the Data Type input doesn’t actu-ally change how the data is stored (the data is still stored in XML), but it causes the Data Page tohandle the field as a date field (it is equivalent to changing the type in the schema).

Page 343: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Unselect the Required checkboxes for each field, with the exception of the ProjectCodefield. This enables you to save a project without necessarily having to fill in every field on theform (you only have to enter a project code before you can save the form). The Base Data Defini-tion input enables you to specify an entry in your data definition file, which defines the defaultvalues for a field’s inputs. For example, click the ProjectStartDate field, and then selectbase_Date as the Base Data Definition. If you don’t enter values for any of the ProjectStartDateinputs, the values will be taken from the base_Date values in the data definition (for a discussionof the base_Date entry itself, see the “Data Definition Entries” sidebar).

DATA DEFINITION ENTRIES

Data definition files consist of a series of entries that define sets of default field values in theRich Data Definition builder. For example, open the default data definition file (/WEB-INF/factory/data_definitions/base_datadef.xml) and navigate to the entry for base_Date(just search for the text base_Date).You should see the following XML element:

<!— date - this assumes internal date format is yyyy/MM/dd —>

<DataDefinition name=”base_Date”>

<DataEntryControl>com.bowstreet.builders.webapp.CalendarPickerBuilder

</DataEntryControl>

<DataEntryInputs>

<Inputs>

<Input name=”ButtonType”>Image</Input>

<Input name=”Label”>...</Input>

<Input name=”ButtonImage”>/factory/images/

calendar/calendar_picker.gif</Input>

<Input name=”Format”

resource_key=”BaseDate_DisplayFormat”>MM/dd/yyyy</Input>

<Input name=”Theme”>blue</Input>

<Input name=”SingleClick”>true</Input>

<Input name=”DefaultLanguage”>en</Input>

</Inputs>

</DataEntryInputs>

<FormatExpr resource_key=”BaseDate_FormatExpr”>Format

(yyyy-MM-dd$MM/dd/yyyy)</FormatExpr>

<TranslateExpr resource_key=”BaseDate_TranslateExpr”>Translate

(yyyy-MM-dd$MM/dd/yyyy)</TranslateExpr>

<ValidateExpr>Date(yyyy-MM-dd)</ValidateExpr>

</DataDefinition>

306 Chapter 11 Field Validation, Formatting, and Translation

Page 344: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The entry for base_Date contains several subelements. The first element, DataEn-tryControl, defines a builder (in this case, a calendar picker) to place a UI data entry controlon the page for the current field.The Inputs element then assigns values for the inputs in thebuilder specified in the DataEntryControl (the Format input is particularly important, as itassigns dates that come from the date picker in the format MM/dd/yyyy). Finally, the threeelements at the end of the base_Date entry list default expressions for formatting, translat-ing, and validating fields. A field assigned to the base_Date entry uses these expressions bydefault, unless they are overridden in the Rich Data Definition builder.

For a complete list of the elements used in the data definition file, refer to the WPFDesigner help.

Adding Date Expressions

Now, select ‘date’ for the Data Type input, which saves the value for the ProjectStartDate field asa date rather than a string. Note the formatting, validating, and translating expression inputs forthe ProjectStartDate field. They are currently blank, which causes the expressions to be takenfrom the base_Date entry in the data definition file. The default formatting expression for thebase_Date entry is as follows:

Format(yyyy-MM-dd$MM/dd/yyyy)

The value in brackets before the $ sign is the format in which you are expecting the date(that is, year, month, and day, in that order), and the part after the $ sign is the format in whichyou would like the date displayed (that is, month, day, and year, in that order). If the date formatdoes not match the format that you expect, then no formatting is applied.

The default expressions should be fine in most cases, but in the current example, you workwith the requirement that dates should be displayed in MM/dd/yyyy format and stored indd/MM/yyyy format. To do this, change the value of the Format Expression field to this expression:

Format(dd/MM/yyyy$MM/dd/yyyy)

This takes dates formatted as dd/MM/yyyy and formats them as MM/dd/yyyy. Now changethe value of the Translate Expression field to this expression:

Translate(dd/MM/yyyy$MM/dd/yyyy)

The value in brackets before the $ sign is the format you would like to translate the date to,and the part after the $ sign is the format you would like the date translated from. The translationlisted converts dates in the MM/dd/yyyy format to the dd/MM/yyyy format.

Because you have now changed the format in which the ProjectStartDate is stored (via atranslate expression), you need to also change the validate expression so that it expects dates inthe new format. To do this, change the Validate Expression input to this expression:

Optional Date(dd/MM/yyyy)

Creating a Projects Portlet 307

Page 345: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This validates the translated field based on the correct format, but only if a value for thefield is entered (that is, it is not mandatory to enter a value for the field).

Make the same changes to the ProjectEndDate field as you just made to the ProjectStart-Date field (setting the Base Data Definition, Data Type, Validate Expression, and TranslateExpression).

Adding a Drop-Down List for the ProjectManager Field

Select the ProjectManager field, and in the Enumeration Values input type, Bob,Sam,Sallywith a leading space before the first comma. This causes the ProjectManager field to be a drop-down box with four values: Bob, Sam, Sally, and a blank value that can be used when the projectmanager is not yet known.

Modifying the ProjectBudget

Select the ProjectBudget field, and change the Base Data Definition input to base_Currency. Thisapplies the default settings for the base_Currency entry; in particular, it defaults the data type ofthe field to decimal and sets the following default formatting expression:

NumberFormat(#,###.00)

This causes numeric values to be separated by a comma every three digits, and have twozeroes appended after the decimal place if no decimal value is explicitly specified.

Change the value of the Translate expression to this expression:

NumberFormat(####.00)

This removes the commas when you save the ProjectBudget field. Also, the default decimaldata type does not have any validation associated with it, so change the Data Type input todouble. Users are not required to enter a value for ProjectBudget, but if they do, the value is vali-dated as a double.

TIP

If you have entered a value for a drop-down input in the Rich Data Definition and you wantto reset that value to use the data definition, you need to set the value to [Default] ratherthan simply change it to a blank value (otherwise, WPF puts the removed value back intothe input after the builder call is saved).

Adding a Regular Expression

The last field modification you will do in this section is the ProjectCode. Say, for example, thatyou want to enforce a particular syntax on project codes (in this case, it is a three-letter code fol-lowed by a single digit). To do this, you should specify a regular expression for the ValidateExpression so that users do not enter invalid codes.

308 Chapter 11 Field Validation, Formatting, and Translation

Page 346: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Select the ProjectCode field, and enter the following expression into the Validate Expres-sion input:

RegularExpression([A-Z][A-Z][A-Z][0-9]$)

This ensures that users enter a valid project code before the project details are saved (formore information on regular expressions, see, for example, Regular Expression Pocket Referenceby Tony Stubblebine).

Save the builder call when you are finished.

Adding Dynamic Validation

Currently, all of the validation you are using in the model is performed on the server by submit-ting the form and reloading the page. To add some dynamic validation to the form, add aDynamic Validation builder call to the model. Change the name of the builder call to dynamic-Validation, and then press the ellipsis button next to the first row in the Fields input. Select theProjectBudget field from the [page1]dataEntry\Items heading and press OK. Finally, change theTrigger Event field to onchange. This causes the validation for the ProjectBudget field to be runwhenever the field is changed. Save the builder call when you are finished.

The next section walks you through the process of testing the various validation, format-ting, and translating settings used on the project form.

Testing the Projects Portlet

Run the projects model again from your IDE. The first area to test is the validation of mandatoryfields. Press the Submit button without entering any values, and you should see a validation errorprinted next to the ProjectCode field as well as at the top of the form in the fullError section of thepage, as shown in Figure 11.5.

Creating a Projects Portlet 309

Figure 11.5 Testing mandatory fields.

Page 347: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

Some of the default validation messages used on the project form are not user friendly. It ispossible to change these messages by using a resource bundle, or adding to or overwritingPortlet Factory’s validation method. These techniques are discussed in the “Further Valida-tion Customizations” section in this chapter.

Enter a project code containing a three-letter code followed by a single digit (such asABC1). Press the Submit button again and you should see the results screen shown in Figure 11.6.Press the Return to project form link to return control to the project form.

310 Chapter 11 Field Validation, Formatting, and Translation

Figure 11.6 Testing validation on the ProjectCode field.

The next test is for the validation on the two date fields. Enter a string of letters for eachdate input and try to submit the form (don’t enter a project code). You should receive validationerror messages for each field.

Try to press the Calendar icon next to each date field, and select a date from the calendarpicker for each field. This populates the date fields with dates specified by the formatMM/dd/yyyy, which is the format specified in the Format input of the base_Date definition (thisformat defines the format of dates returned from the date picker, and is separate to the formattingformula you applied to the field, which is evaluated only when the form is submitted). Submit theform, and you should have no validation errors for the date fields (later in this chapter, you seehow you can add validation to these dates to ensure that the end date occurs after the start date).Now, type the date 15/03/2008 for both date fields. Submit the form again, and you should see

Page 348: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

that the dates have been converted to the format MM/dd/yyyy, courtesy of the respective format-ting formula for each field.

Test the validation for the ProjectBudget field. Enter a string of letters and submit theform—you should see validation error messages displayed next to the ProjectBudget field as wellas at the top of the form. Enter a numeric value with more than three digits and submit the form.The value for the field should be modified to include commas after every three digits and toappend a decimal place to the number followed by two zeroes if you don’t enter a decimal value.

The final test is to test the translation expressions for the date fields and the ProjectBudgetfield. To do this, enter valid dates for both date fields using the date pickers, and then enter a num-ber with more than four digits in the ProjectBudget field. You need to also enter a valid projectcode so that you can successfully submit the form. When you submit the form, check the ‘Results(translated values)’ section of the confirmation page and you should see that the dates have beentranslated to the format dd/MM/yyyy (rather than the default translation of yyyy-MM-dd). Youshould also see that the commas have been removed from the ProjectBudget field.

After you have tested the projects model, you should rebuild your application on the portalserver (for instructions on how to do this, see the example in Chapter 1), after which you can viewthe projects model as a portlet on the portal server. After you have added the Project Form portletto a page in the portal, it should display as shown in Figure 11.7.

Testing the Projects Portlet 311

Figure 11.7 The Project Form portlet.

The next section of this chapter describes how to write a custom formatter class to cus-tomize the formatting, validation, and translation used in the ProjectManagerContactNo field.

Page 349: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

312 Chapter 11 Field Validation, Formatting, and Translation

Writing a Formatter Class

The functionality for the various translating, validating, and formatting expressions in WPF aretaken from a Java class called a formatter class. By default, this functionality comes from a for-matter class called StandardFormatter; however, if you need to modify this functionality, you canwrite your own formatter class using the IInputFieldFormatter interface.

This section describes how you can add a formatter class to your WPF project, which addsthe following functionality to the ProjectManagerContactNo field:

• The field is formatted so that spaces are added every three characters from the end of thenumber.

• The field is translated so that spaces are not stored as part of the number.

• The field is validated so that only numeric values are allowed.

The following builders are added in this section:

• Comment

• Linked Java Object

• Data Field Modifier

Adding a Formatter Class

To facilitate this functionality, the first step is to add the formatter class itself, after which you canadd builders to utilize the formatter’s functionality. If you have access to ibmpressbooks.com/title/9780137134465, download the com folder from the Chapter 11 link on the site, thencopy it into your WebContent/WEB-INF/work/source directory of your project. This adds theCustomFormatter class to your project. If you are able to do this successfully, skip to the “TheCustomFormatter Class” section. Otherwise, you need to add the class manually. To do this, openthe New Java Class dialog in the WPF Designer by clicking File, New, Class. Specify the packageas com.ibm (substituting your own company name for ibm), and then change the name of theclass to CustomerFormatter (note that the package com.ibm is used throughout this chapter,but in each case, you should substitute your own company name for ibm). Press the Finish button,which creates a skeleton source file in the appropriate package in the WebContent/WEB-INF/work/source directory.

Change the contents of the CustomFormatter.java file so that they read as shown in the fol-lowing, and then save the file when you are finished:

package com.ibm;

import java.util.ArrayList;

import java.util.List;

import com.bowstreet.methods.IInputFieldFormatter;

import com.bowstreet.webapp.WebAppAccess;

Page 350: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

public class CustomFormatter implements IInputFieldFormatter {

private String errorMessage;

private WebAppAccess webApp;

//These Lists define the available expressions

protected static List formatExpressionList = null;

protected static List translateExpressionList = null;

protected static List validateExpressionList = null;

//These Strings define the content of the Lists

public final static String ADDSPACES = “Add spaces to phone number”;

public final static String REMOVESPACES = “Remove spaces from phone number”;

public final static String VALIDATEPHONENUMBER = “Validate phone number”;

//Set the contents of each List

private static final String[] formatExpressions = {ADDSPACES};

private static final String[] translateExpressions = {REMOVESPACES};

private static final String[] validateExpressions = {VALIDATEPHONENUMBER};

static

{

formatExpressionList = makeList(formatExpressions);

translateExpressionList = makeList(translateExpressions);

validateExpressionList = makeList(validateExpressions);

}

//Used for formatting

public String format(String value, String expression)

{

String result = value;

StringBuffer modifiedResult = new StringBuffer();

if(getErrorMessage() == null)

{

if (expression.equals(ADDSPACES))

{

//Insert a space every three characters from the end

for (int index=result.length(); index >= 0; index=index-3)

{

if (index-3 >= 0 )

modifiedResult.insert(0, “ “ + result.substring(index-3, index));

else

Writing a Formatter Class 313

Page 351: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

modifiedResult.insert(0, result.substring(0, index));

}

result = modifiedResult.toString();

}

}

return result;

}

//Used for translation

public String translate(String value, String expression)

{

String result = value;

if (expression.equals(REMOVESPACES))

{

//Remove spaces

result = result.replaceAll(“ “, “”);

}

return result;

}

//Used for validation

public boolean validate(String value, String expression)

{

boolean result = true;

//Reset error message

setErrorMessage(null);

if(expression.equals(VALIDATEPHONENUMBER))

{

//Check to see if phone number contains letters

for(int index = 0; index < value.length(); index++)

{

if (value.charAt(index)<48 || value.charAt(index)>57)

{

setErrorMessage(“Phone numbers cannot contain letters.”);

result=false;

}

}

}

return result;

}

314 Chapter 11 Field Validation, Formatting, and Translation

Page 352: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

//These methods are required by the interface

public void setErrorMessage(String msg) { errorMessage = msg; }

public String getErrorMessage() { return errorMessage; }

public void setWebAppAccess(WebAppAccess webApp) { this.webApp = webApp; }

public WebAppAccess getWebAppAccess() { return webApp; }

public void setTranslateSuccessFlag(boolean parm1) { }

public boolean getTranslateSuccessFlag() { return true; }

public List getFormatExpressionList() { return

�formatExpressionList; }

public List getTranslateExpressionList() { return

�translateExpressionList; }

public List getValidateExpressionList() { return

�validateExpressionList; }

//This method creates a list from a String array

protected static List makeList(String[] array)

{

List list = new ArrayList(array.length);

for (int i = 0; i < array.length; i++)

list.add(array[i]);

return list;

}

}

The CustomFormatter Class

After you have finished adding the CustomFormatter class to your project, there are severalpoints of interest in the CustomFormatter class that you should be aware of. The three main meth-ods in the class—format, translate, and validate—are used to provide functionality for the variousexpressions specified in the builders. Each method takes in a value and an expression; the value isthe data to be modified, and the expression is a string denoting how the data should be modified.These expression strings are defined by the three List objects in the class (formatExpressionList,translateExpressionList, and validateExpressionList), and the contents of these List objects dis-play in the expression dropdowns in the Data Field Modifier. For example, the formatExpressionADDSPACES declares that spaces be added to a phone number. If ADDSPACES is selected forthe Format Expression input in the Data Field Modifier, then the format method will receiveADDSPACES for its expression argument whenever that field is formatted. The format methodcan then run the appropriate code to format the field value passed in.

Adding a Linked Java Object

You now need to make some changes to the projects model to utilize the new formatting class.First, add a Comment builder call to the model and call it Custom Formatter. This comment

Writing a Formatter Class 315

Page 353: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

separates builder calls in previous sections from the builder calls used for the custom formatter.Save the builder call.

Add a Linked Java Object builder call to the model. This builder call provides a link to theCustomFormatter class from the projects model, so that it can be used as if it was part of themodel. Change the name of the builder call to customFormatter, and then specify the Class Nameas com.ibm.CustomFormatter (substituting your own company name for ibm). Save thebuilder call when you are finished. The CustomFormatter class is now available as a formatter foryour form fields, which you can specify using a Data Field Modifier.

Adding a Data Field Modifier

Add a Data Field Modifier builder call to the model and name it formatContactNo. In theFields section, specify the ProjectManagerContactNo field for both page1 and page2 by pressingthe ellipsis button at the end of the first row, and then selecting the appropriate field from underthe [page1]dataEntry\Items and [page2]displayResults/Items headings.

Scroll down to the Formatting section of the builder call, and select com.ibm.CustomFor-matter for the Formatter Class input (again, substitute your own company name for ibm). The val-ues for the various List objects in your CustomFormatter class (that is, formatExpressionList,translateExpressionList, and validateExpressionList) should now be available as expressions inthe inputs in this section. Select ‘Add spaces to phone number’ for the Format Expression,‘Remove spaces from phone number’ for the Translate Expression, and ‘Validate Expression’ forthe Validate Expression inputs, and then save the builder call when you are finished.

To test your custom formatter class, run your model and enter several letters for the Project-ManagerContactNo field. When you submit the form, you should receive a validation error.Change the phone number so that it is a numeric value, and after you submit the form, you shouldnotice that spaces have been added every three characters from the right of the number. Finally,enter a valid project code so that the form submits without raising a validation error. On theresults page, you should see that the translation method has removed the spaces from the number.

Further Validation Customizations

In this section, two further customizations to the validation process are discussed. The firstinvolves changing the validation messages displayed to the user via a properties file called aresource bundle; these files can then be easily transferred between projects. The second cus-tomization involves adding a method to the validation process, which gives you a better under-standing of how WPF handles validation and translation, and also gives you more control overhow the validation and translation in your model are performed.

Adding a Resource Bundle

To add a resource bundle to your project, first open the dataEntry Data Page builder call in yourprojects model, and scroll down to the Label Translation Settings section. Press the CreateResource Bundle button, and then navigate to the WebContent/WEB-INF/work/source directory

316 Chapter 11 Field Validation, Formatting, and Translation

Page 354: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

of your project. Type the name of the properties file as projectForm.properties and pressthe Save button. Change the Resource Bundle Name input to projectForm, and then save thebuilder call. After the builder call is saved, the projectForm.properties file is created in yoursource directory; it is used to provide validation messages for the Data Page.

Open the projectForm.properties file. It should display as shown in the following:

dataEntry=dataEntry

dataEntry=dataEntry

Project_Code=Project Code

Project_Manager=Project Manager

Project_Manager_Contact_No=Project Manager Contact No

Project_Start_Date=Project Start Date

Project_End_Date=Project End Date

Project_Budget=Project Budget

ErrorMessage.Boolean=Not recognized as a Boolean value.

ErrorMessage.DateTime=Not recognized as a DateTime value.

ErrorMessage.FloatingPoint=Not recognized as a Floating Point

�value.

ErrorMessage.Integer=Not recognized as an Integer value.

ErrorMessage.Required=This field is required.

The first section of the properties file lists field labels that are displayed for validation mes-sages, and the second section lists the validation messages themselves. Note that WPF automati-cally inserts underscores into the field names, but this won’t affect any of the validation. Noticealso that there is no entry to redefine messages for regular expressions; if you want to modify aregular expression message, you need to modify or add to the validation procedure itself (whichyou can do after the resource bundle has been configured and tested). Also, notice the two entriesfor dataEntry—these entries are for the page1 and page2 Data Pages themselves and are not used.Delete the two dataEntry lines from the properties file.

TIP

If you have disabled automatic builds in the WPF Designer, you will need to manuallyrebuild your project before the properties file can be used (which you can do by pressingCtrl+B).

Some of the error messages are not needed, and the ones that are needed should be modi-fied so that they are user friendly. Modify the properties file so that it displays as shown below,and then save it when you are finished:

Project_Code=Project Code

Project_Manager=Project Manager

Further Validation Customizations 317

Page 355: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Project_Manager_Contact_No=Project Manager Contact No

Project_Start_Date=Project Start Date

Project_End_Date=Project End Date

Project_Budget=Project Budget

ErrorMessage.DateTime=Must be a valid date.

ErrorMessage.FloatingPoint=Must be a valid dollar amount.

To test the resource bundle, run your projects model and enter invalid values for the Pro-jectStartDate, ProjectEndDate, and ProjectBudget fields. The validation messages displayedshould now be taken from the resource bundle.

Changing Messages for Regular Expressions

To change the message for a regular expression, you can either modify the validate method of aformatter class, create a post-save action, or modify Portlet Factory’s validation methods. Thevalidation process is contained in a method called page1_SaveData, which WPF creates automat-ically whenever you have a Data Page builder call in your model containing data entry fields.Although you can change this method by overwriting it with a Method builder call, the process iserror-prone, and it is recommended you create a post-save action instead. Post-save actions areparticularly useful when you want to validate a field’s value in relation to another field’s value.

In the example that follows, you can see how to change the validation message for the Pro-jectCode field and how to validate the date for the ProjectEndDate field to make sure it occursafter the ProjectStartDate.

To complete this section, you need to add the following two builders to the projects model:

• Comment

• Method

Creating the Post-Save Action

Add a Comment builder call to the model and call it Custom Save. This comment sections offthe previous builder calls from the builder calls used for the custom formatter. Save the buildercall.

Select the WebApp Tree tab in the Model Editor, and then navigate to the WebApp/Methodsection. The page1_SaveData method is not listed because it is hidden by default, but you can dis-play it by selecting Window, Preferences in the WPF Designer, and then enabling the ‘Show hid-den objects’ checkbox from the WebSphere Portlet Factory Designer section. After you havedone this, the page1_SaveData method should display in the WebApp Tree under the WebApp/Method section.

Select the page1_SaveData method, and then click the code listing on the right side of thescreen. Copy the contents of the page1_ SaveData method (the curly braces and everything that isbetween them) to the Clipboard by highlighting it and pressing Ctrl+C. When you create a post-save method in the next step, you will use the contents of the Clipboard as a starting point.

318 Chapter 11 Field Validation, Formatting, and Translation

Page 356: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Now add a Method builder call to the model. Name the builder call additionalValida-tion, and paste in the Java code from the Clipboard to the Method Body input. Notice the codesteps through each field applying validation and translation formulas specified in your buildersusing the appropriate formatter classes. Take, for example, the following code fragment, whichprocesses the ProjectBudget field:

str = webAppAccess.getRequestInputs()

�.getInputValue(“ProjectBudget”);

formatter = (IInputFieldFormatter)variables

�.getObject(“StandardFormatter”);

str = formatter.translate(str, “NumberFormat(###0.0)”);

if (!formatter.validate(str, “Optional Floating Point Number”))

errors.addMessage(“ProjectBudget”, formatter.getErrorMessage());

dataEntry.setText(“ProjectBudget”, str);

This code first gets the input value for the ProjectBudget field, and then it retrieves theappropriate formatter class—StandardFormatter in this case (all of your fields use StandardFor-matter, except the ProjectManagerContactNo field). It then translates the field value using thetranslate expression specified in the Rich Data Definition builder call, and then validates it usingthe default validation expression for the double data type. If the validation fails, the appropriateerror message for that validation method is taken from the formatter class. The final line insertsthe translated value into the dataEntry variable.

WARNING

Be careful if you are overwriting the page1_SaveData method, as any changes you make toyour validation, formatting, or translating at the builder level can no longer be incorporatedinto the method. To incorporate such changes, you need to disable your page1_SaveDatamethod, and then copy the new modifications from the page1_SaveData method created byWPF (which you can access from the WebApp Tree tab in the Model Editor).

Because of the maintenance difficulties this approach can cause, a custom save methodis generally not advisable unless it is not possible to perform your changes using a differenttechnique.

Modifying the Post-Save Action Code

Because this validation is already being run, you don’t actually need all of the code. Remove allof the code, except for the top section of the method and the part that validates the ProjectCode.When you are finished, your code should display as shown in the following:

{

String str;

Variables variables = webAppAccess.getVariables();

Further Validation Customizations 319

Page 357: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

IInputFieldFormatter formatter;

PageAutomationMessages errors =

�(PageAutomationMessages)webAppAccess.getVariables().getObject

�(“page1Error”);

errors.clear();

IXml dataEntry = variables.getXml(“dataEntry”);

if (dataEntry == null) {

dataEntry = XmlUtil.create(“Items”);

variables.setXml(“dataEntry”, dataEntry);

}

str = webAppAccess.getRequestInputs().getInputValue(“ProjectCode”);

formatter = (IInputFieldFormatter)variables

�.getObject(“StandardFormatter”);

if (!formatter.validate(str, “RegularExpression([A-Z][A-Z][A-Z]

�[0-9]$)”))

errors.addMessage(“ProjectCode”, formatter.getErrorMessage());

dataEntry.setText(“ProjectCode”, str);

}

To change the validation message displayed for the ProjectCode field, locate the section ofcode that pertains to the ProjectCode field and modify the line containing the addMessagemethod so that it reads as follows:

errors.addMessage(“ProjectCode”, “Must be a valid project code (three

�uppercase letters followed by a single digit)”);

Now, just before the last curly bracket at the bottom of the code, add the Java code shown inthe following code. This validates the ProjectEndDate to see if it occurs after the ProjectStart-Date.

//check to see if project start date is before project end date

if ( ! webAppAccess.getRequestInputs().getInputValue(“ProjectEndDate”).

�equals(“”) && !

�webAppAccess.getRequestInputs().getInputValue(“ProjectStartDate”).

�equals(“”))

{

try

{

java.text.SimpleDateFormat format = new

�java.text.SimpleDateFormat(“dd/MM/yy”);

320 Chapter 11 Field Validation, Formatting, and Translation

Page 358: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Date startDate =

�format.parse(webAppAccess.getRequestInputs().getInputValue

�(“ProjectStartDate”));

Date endDate =

�format.parse(webAppAccess.getRequestInputs().getInputValue

�(“ProjectEndDate”));

if ( endDate.before(startDate) )

errors.addMessage(“ProjectEndDate”, “Must be after the project

�start date.”);

}

catch (java.text.ParseException pe)

{

errors.addMessage(“ProjectEndDate”, “Must be after the project

�start date.”);

}

}

Save the builder call when you are finished.

Running the Post-Save Action

To use the additionalValidation method as a post-save action, open the dataEntry Data Page andscroll down to the Required Field and Input Validation Settings section. Select additionalValida-tion for the Post-Save Method input and save the builder call.

To test the new save method, run your model again from the IDE and check to see whetherthe message for ProjectCode has changed. Then, enter a ProjectEndDate that occurs before theProjectStartDate, and see if you get a validation error when you submit the form. Finally, makesure that when you put in valid values for these fields, the form submits successfully!

Summary

In this chapter, you learned how to add field level validation, formatting, and translating to yourportlets. A number of different techniques were discussed, such as the use of the Rich Data Defi-nition, Data Page, Data Field Modifier, and Dynamic Validation builders, as well as resource bun-dles, regular expressions, data definitions, and custom Formatter classes. You also built a portletthat provides the facility to enter details for new projects in a simple project application, whichdemonstrates the use of the techniques just mentioned.

Chapter 12, “Profiling Portlets,” discusses how to use profiling to cater to the different con-texts and states in which your WPF applications are used.

Summary 321

Page 359: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Important Points

• There are numerous ways in which formatting, validating, and translating can be addedto fields in WPF applications. The best approach is to use a Rich Data Definition builderwhen dealing with schema typed fields, and use a Data Field Modifier for fields thataren’t defined by a schema.

• The Data Page builder lets you present a variable as a set of fields on a form, but it alsoprovides validation settings not available in other builders (such as setting post savemethods and defining a tag name where validation messages will appear).

• The Data Page builder automatically creates methods for your validation processescalled page1_saveData and page1_nextAction, where page1 is the name of the HTMLpage where the Data Page resides.

• The Dynamic Validation builder enables you to add client-side validation to your appli-cations.

• You can modify validation messages using a resource bundle.

• A formatter class is a class that provides functionality for validation, formatting, andtranslation in WPF. A class called StandardFormatter is used by default, but you canwrite your own formatter class using the IInputFieldFormatter interface.

322 Chapter 11 Field Validation, Formatting, and Translation

Page 360: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

323

C H A P T E R 1 2

Profiling Portlets

One of the three core architectural components of WebSphere Portlet Factory (WPF) applications(in addition to models and builders) is profiles. In this chapter, you use profiling to customize acompany announcements portlet. By the end of the chapter, you will have a portlet that displaysannouncements tailored to the user’s language (in either English or Spanish) and department (ITor HR), and you will apply this knowledge to profile portlets in other WPF applications.

The files used in this chapter are available for download from ibmpressbooks.com/title/9780137134465, under the Chapter 12 folder (instructions for copying these files into yourproject are included in a readme.txt file in the same folder); however, to increase your under-standing of the topics discussed in this chapter, it is recommended that you create these files your-self by following the example in this chapter.

The following topics are covered in this chapter:

• Profiling builder inputs

• Creating an announcements portlet

• Creating a custom selection handler

Profiling Builder Inputs

A profile in WPF is a set of values that can be assigned to builder inputs, enabling you to build mul-tiple variations of a portlet from the same code base. These values are assigned to builder inputsbased on certain contexts, roles, or settings. For example, the portlet you develop in this chapterwill contain two XML documents: one will have company announcements in English and theother will have them in Spanish. The items displayed to the user will be determined by the user’scurrent locale, and profiles will be created for each country and language that the applicationsupports: US English (US is the country code for the United States of America) and ES Spanish

Page 361: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

(ES is the country code for Spain). Each profile will contain values used to print an appropriateheading for the announcements, and each will have values to enable or disable announcementsbased on the current department that the user belongs to (HR or IT). These profile values will beused to populate various builders in the model, so that whenever a request to the portlet is made,the appropriate values for the inputs will be taken from the correct profile (so English-speakingusers can see the English announcement items for their department, and Spanish-speaking userscan see the Spanish items for their department). See the “Profiles” section of Chapter 1, “Intro-duction to WebSphere Portlet Factory,” for a more in-depth discussion of how this process worksin WPF.

WPF decides how to map portlet requests to particular profiles using a mechanism knownas a selection handler. WPF comes with a number of different selection handlers, which automat-ically provide the facility to map profiles in a host of different situations (for a description ofthese handlers, see the “Default Selection Handlers” sidebar). The functionality for the defaultselection handlers is provided by Java classes stored in the selectionhandlers.zip file under theWEB-INF/work directory, and each selection handler is configured using an XML configurationdocument (found under WEB-INF/config/selection_handlers). Although you don’t necessarilyneed to worry about these files when profiling your applications, you can use them as a basis forcreating your own custom selection handlers (although the default selection handlers should besufficient in the majority of cases).

DEFAULT SELECTION HANDLERS

WPF provides a number of selection handlers out of the box, which can be used to mapportlet requests to profiles. These selection handlers are listed here:

Explicit handler—This handler enables you to explicitly specify a particular profile (adefault profile is used if no profile is selected).

File Segment handler—This handler maps requests to profiles through user-profile map-ping defined in a simple XML file.

J2EE Role handler—This handler maps requests to profiles using J2EE roles (for example,a particular profile might be mapped when users have the System Administrator role).

LDAP Group-Based selection handler—This handler associates LDAP groups with par-ticular profiles. You need to configure this handler’s XML configuration file (ldapselection-handler.xml) to use it, specifying such things as the LDAP server and LDAP bind user.

Locale selection handler—This handler maps requests by associating locales (forexample, en or en-US) with profiles.

Portal Execution Mode handler—This handler maps requests to profiles depending on themode in which the application is executed. There are two possible modes: Standalone andPortal.

324 Chapter 12 Profiling Portlets

Page 362: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

User Attribute handler—This handler enables you to map requests by associating a userattribute (such as uid or cn) with a particular profile. You can change the attribute used byconfiguring the XML configuration file (userattributehandler.xml).

WP Composite Application Role selection handler—This handler maps profiles torequests through WebSphere Portal Composite Application roles.

WPS Group Segment handler—This handler maps requests to profiles based on theirWebSphere group. This handler doesn’t require any configuration, so it is a simpler alterna-tive to the LDAP Group selection handler if your WebSphere groups are the same as thegroups defined in your LDAP directory.

WPS Execution Mode handler—This is a deprecated version of the Portal Execution Modehandler, used only for backward compatibility. Use the Portal Execution Mode handler fornew applications.

In this chapter, you use two of the default selection handlers to map requests to profilesbased on user locales and the WebSphere Portal Server group that the current user belongs to: theLocale selection handler and the WPF Group Segment handler (this does not require you to mod-ify the selection handlers in any way).

Creating an Announcements Portlet

In this section, you build a portlet that displays company announcements in one of two possiblecountry and language combinations (US English and ES Spanish), tailored to one of two com-pany departments (HR and IT). A screenshot of the finished portlet is shown later in Figure 12.10.

Before you proceed with this section, be sure you have a WPF project to contain the portlet.If you have a project from a previous chapter, you can use it; otherwise, you should create a newWPF project (for more information on creating projects, see Chapter 1). The project will be pub-lished as a WAR file and deployed to a portal server, and you should also deploy the application toa local application server for testing.

After you have a project set up, you need to add a model to the project (which will be sur-faced to the portal server as the company announcements portlet). This model uses the followingbuilders to provide its functionality:

• Action List

• Page

• Portlet Adapter

• Localized Resource

• Text (x2)

• Import to XML

• Data Page (x2)

Creating an Announcements Portlet 325

Page 363: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Model

Create a new model called companyAnnouncements in your project, under the folder WEB-INF/models/chapter12. The model should be based on the Main and Page template, using a PageType of Simple Page. For more information on creating models, see the example in Chapter 1.After it is created, your model should have two builders in it: an Action List called main and aPage called page1. The Action List runs automatically whenever the model is run, and it opensthe page1 Page.

Modifying the Page

Open the Page builder, and change the contents of the Page Contents (HTML) input to the HTMLthat follows:

<html>

<body>

<div align=”center” style=”font:12pt Arial;font-weight:

bold;color: #336699;”>Announcements</div>

<!—begin HR news —>

<br>

<br>

<div align=”center” style=”font:12pt Arial;font-weight: bold”>

<span name=”hrHeader”></span>

</div>

<span name=”hrNews”></span>

<!—end HR news —>

<!—begin IT news —>

<br>

<br>

<div align=”center” style=”font:12pt Arial;font-weight: bold”>

<span name=”itHeader”></span>

</div>

<span name=”itNews”></span>

<!—end IT news —>

</body>

</html>

This page contains span tags for displaying two separate news sections. The first section isfor the HR announcements and consists of hrHeader and hrNews. The heading for the HRannouncements is placed at the hrHeader tag, and the HR announcements themselves are placed

326 Chapter 12 Profiling Portlets

Page 364: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

at hrNews. Similarly, the itHeader tag is replaced with the heading for the IT announcements, andthe IT announcements are then displayed at the itNews tag.

Save the builder call when you are finished.

Adding a Portlet Adapter

You add a Portlet Adapter builder call to your model to surface your model as a portlet when theapplication is deployed to a portal server. To do this, select Portlet Adapter from the BuilderPalette (you can open the Builder Palette by clicking the icon in Outline view) and press OK.Name the Portlet Adapter companyAnnouncements, and then change the Portlet Title toCompany Announcements and the Portlet Description to This portlet displays companyannouncements. This surfaces the model as a portlet called Company Announcements. Save thebuilder call when you are finished.

Creating a Default Resource Bundle

In this example, you localize the heading strings for the announcements so that they pertain to aspecific country and language. There are a number of ways to do this, but perhaps the bestapproach is to create a resource bundle for each country and language combination (one for USEnglish and one for ES Spanish) to hold the text for the announcement headings. After you havedone this, you can then use profiling and the Localized Resource builder to access the headingtext. Using resource bundles enables you to easily modify and transfer localized properties with-out needing to modify any code, and this is the approach adopted in this example.

The first resource bundle you need to create is a default resource bundle that can be used ifno other resource bundle can be matched against the current user’s country and language. Tocreate the default resource bundle in the WebContent/WEB-INF/work/source/com/ibm folder ofyour project, create a plain text file called companyAnnouncements.properties, substitutingibm for the name of your company (note that the package com.ibm is used throughout this chap-ter, but in each case you should substitute your own company name for ibm). You can create aplain text file by selecting File, New, Other in your IDE to open up the Select a Wizard dialog,and then select File from under the General category.

Open the companyAnnouncements.properties file and enter the following text:

# localized resources for companyAnnouncements portlet

announcements.hrHeader=English HR Announcements

announcements.itHeader=English IT Announcements

This makes two string properties available (the HR and IT headings) in English, which willbe the default language that your portlet supports. You access these properties from the LocalizedResource builder later. Save the file when you are finished.

Creating a US English Resource Bundle

Because the default resource bundle is already using US English, you don’t really need a separateresource bundle for US English users. However, it is a good idea to create one anyway, just in

Creating an Announcements Portlet 327

Page 365: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

case you decide to modify the default resource bundle later (and you want to leave the US Englishsettings intact). To do this, in the WebContent/WEB-INF/work/source/com/ibm folder of yourproject create a plain text file called companyAnnouncements_en_US.properties (afteragain substituting ibm for the name of your own company). The first part of this filename, com-panyAnnouncements, is the name of the resource bundle. The next part (after the first underscore)is the language of the resource bundle, followed by the country code after the second underscore.Portlet Factory recognizes this naming convention, so that when you configure the LocalizedResource builder later in the chapter, you can specify builder inputs for the name of the resourcebundle (companyAnnouncements), the name of the country, and the name of the language. Thisthen reads in the text from the appropriate resource bundle (the inputs are profiled so that they canbe set based on the country and language settings for the current user).

Open the companyAnnouncements_en_US.properties file and enter the same text as youdid for the default resource bundle. Save the file when you are finished.

Creating an ES Spanish Resource Bundle

Now create another blank text file in the same directory as the other resource bundles, and thistime, call it companyAnnouncements_es_ES.properties. Enter the announcements asshown in the following:

# localized resources for companyAnnouncements portlet

announcements.hrHeader=Español Anuncios de Recursos Humanos

announcements.itHeader=Español Anuncios de Informática

These are the ES Spanish equivalents to the US English announcements you just created.Save the file when you are done adding the announcements.

Localizing the Announcement Headings

Now that you’ve created the resource bundles, you need to use a Localized Resource builder toaccess them from WPF. The Localized Resource builder can make some methods available inyour model that will enable you to reference the text of specific properties in your resourcebundles.

Add a Localized Resource builder call to your model by selecting Localized Resource fromthe Builder Palette and then pressing OK (you can open the Builder Palette by clicking the iconin Outline view). Name the builder call localizedResources, and then select com.ibm.company-Announcements for the Resource Bundle Name input. This specifies the default resource bundlefor the Localized Resource builder; the variants of this resource bundle (that is, the US English andES Spanish resource bundles) can be accessible depending on how you set the remaining builderinputs. For example, if you type en for the Language input and US for the country input, this willcause your localized text to be read from the companyAnnouncements_en_US.properties file. Ide-ally, however, you need these inputs to be dynamic; that is, if the user’s country and language areES and es, respectively, it would be useful if the values of the inputs could be retrieved based onthese settings. To do this, you need to profile the Country and Language inputs.

328 Chapter 12 Profiling Portlets

Page 366: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Profiling the Language Input

Profile the Language input by pressing the icon to the left of the Language input. This opensthe Profile Input dialog shown in Figure 12.1.

Creating an Announcements Portlet 329

Figure 12.1 The Profile Input dialog.

The Profile Input dialog enables you to configure profiling for a particular builder input.There are three main points of configuration on this dialog: the Profiles, Profile Entry, and ProfileSet, and their purposes will become clearer as you progress through this section. In the Profilesarea, you define different scenarios that you want to cater for (in this case, US English and ESSpanish); the profile entry describes the value for the builder input (in this case, the language ofthe resource bundle that you want to display). The profile set is simply a container for the profilesand profile entries, which you can access later after your settings have been saved. For a summaryof the profiling terms used in this chapter, please refer to the “Profiling Terminology” sidebar.

PROFILING TERMINOLOGY

The following list summarizes and briefly describes the basic profiling terms used in thischapter:

Profiled input—A profiled input is a builder input that takes its value from a value in a pro-file.

Profile entry—Profile entries are points of variance in an application. Profile entry valuesare given to builder inputs when a builder input is profiled.

Profile—Profiles are collections of values for profile entries to be used in a certain contextor for a particular role.

Profile set—Profile sets are containers of profile entries and profiles.

Page 367: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Segment—A segment is the context associated with a profile (for example, your segmentsmight be J2EE roles if you use a J2EE role handler).

Selection handler—Model requests are assigned to a profile using an algorithm specifiedby a selection handler. For example, this algorithm might use something like the user’s cur-rent language preferences or LDAP attributes to determine the profile to assign to therequest.

The first thing you need is a profile set. Profile sets are stored as files with a .pset extensionin the WEB-INF/profiles directory, and can be used to configure your profiles. After you pressOK on the Profile Input dialog, the values you enter are saved in the profile set specified in theProfile Set Name field. By default, WPF creates a new profile set for you the first time you profilea builder input in the model, using the name of the model followed by the suffix ‘ps’ (com-panyAnnouncementsps). The name of the default profile set is not overly descriptive, so create anew profile set by clicking the Create Profile Set button. In the New Profile Set dialog that fol-lows, enter localeValues for the Name, and Localization settings for the Description.Don’t base the profile set on an existing one (that is, leave the dropdown at the bottom of the dia-log set to <none>). Press OK when you are finished, and you should see that the Profile Set Namefield has been set to the name of the new profile.

Next, you need a profile entry that defines the type of value you will insert into the Lan-guage input. The default suffices: a profile entry called LocalizedResource_Language. If youwant to see the settings used for this profile entry, press the Create Entry button, which displays adialog to enter a new profile entry but uses the settings of the LocalizedResource_Language pro-file entry as a starting point (press Cancel when you have finished looking at this dialog, as youdon’t want to create a new profile entry in this instance). For a description of the fields used foreach profile entry, see the “Profile Entries” sidebar.

PROFILE ENTRIES

Profile entries describe the values assigned to builder inputs from profiles, and are an inte-gral part of the profiling process. Each profile entry is made up of a number of fields, whichare briefly listed and described in the following list:

Name—This field denotes how the profile entry displays in the profile set editor and the Pro-file Input dialog.

Prompt—This field denotes text that displays when you set the profile entry value in theWPF Designer. If you enable the setting of profiles through the portlet configure and portletedit pages in the Portlet Adapter builder, then this field also denotes text that displays next tothe profiles on these pages.

330 Chapter 12 Profiling Portlets

Page 368: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

UI Type—This field changes the type of UI controls that display when changing the profileentry value in the IDE, portlet configuration page, or portlet edit page. Additional profile entryfields (such as Width) may display in the profile set editor depending on the value given tothe UI Type field.

Default Value—This field provides a value for the profile entry in the Default profile (which issubsequently given to other profiles as well, unless you change them).

Execution Time—This field indicates when the value of the profile entry is assigned. If thevalue is set to false (the default), the value is evaluated at generation time (when theWebApp is generated). A profile value that is evaluated at generation time can potentiallyresult in a different WebApp being generated for each possible value. If the field is set totrue, then the value is evaluated at execution time (that is, when a user executes the appli-cation). In this case, only one WebApp is generated, and shared across each potential pro-file/model combination. To help decide which setting to use, think about how the value isused. If the builder input affects generation, it should be set to false (for example, languageand country settings in the Localized Resource builder are normally read in at generationtime). If the input supports an indirect reference (that is, one that enables a value of ${…} ),then you should set the execution time field to true. Builder inputs such as Button labels andHTML attributes should almost always be evaluated at execution time.

The final section of this dialog is the Profiles section, which is where you define the differ-ent contexts that give the Language input different values. A profile called Default is alreadylisted in this section—this profile is used if there are no other profiles, or if another profile cannotbe assigned. The Profile Values column lists the value each profile gives to the profile entry (inthis case, the value given to the Language input). For this example, you want the default Lan-guage to be ‘en’, so enter the text en into the Profile Values column next to the Default profile.

To create a new profile, press the Create Profile button and type USEnglish as the profilename. Press OK when you are finished, and then press the Create Profile button again, this timenaming the profile ESSpanish. Press OK when you are finished, and two new profiles should belisted under the Default heading in the profiles section.

Place the cursor in the row for the USEnglish profile in the Profile Values column, and typethe value en. This is done so that whenever the USEnglish profile is used, the profile entry Local-izedResource_Language has this value; it is then assigned to the Language input in the LocalizedResource builder. Do the same for the ESSpanish profile, except specify the value as es.

You have now finished configuring the Profile Input dialog. When you press OK, a profileset called localeValues.pset is created in the WEB-INF/profiles directory and it contains a profileentry called LocalizedResource_Language. The profile set also contains two profiles—ESSpan-ish and USEnglish—which will give a different value to the profile entry when each is used. If noprofile is used, the value en is used.

Press OK to accept the changes. The Language input now becomes blue to indicate it hasbeen profiled, and the input itself is grayed out (as shown in Figure 12.2).

Creating an Announcements Portlet 331

Page 369: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 12.2 The profiled Language input.

TIP

You can remove profiling from a field at any time by pressing the Remove Profiling buttonon the Profile Input dialog.

Profiling the Country Input

You should now profile the Country input. To do this, open up the Profile Input dialog by pressingthe icon next to the Country input in the Localized Resource builder call, and then make surethe localeValues profile set is selected for the Profile Set Name. The default settings for the pro-file entry (LocalizedResource_Country) are sufficient, so there is no need to modify them.

You are using the same profile set as before, so the profiles you created earlier can be usedfor the Country input; all you need to do is set the appropriate values. To do this, type US for theUSEnglish profile and Default profile, and type ES for the ESSpanish profile. One of these valuesis then used for the Country input, depending on the profile matched to a given request. Press OKto close the Profile Input dialog, and the Country input will become blue to indicate it has beenprofiled. Save your changes to the builder call.

Setting a Selection Handler

By default, your profile set can use the Explicit Handler as its selection handler, which means thatyou need to explicitly assign profiles to use them. You can explicitly assign profiles programmat-ically, or by giving users a configuration page that they can use to pick a profile. In this example,you need to change the selection handler, as you want to be able to link your profiles to particularlocales. To do this, double-click the localeValues.pset profile set in the WEB-INF/profiles direc-tory, which opens the profile in the Profile Set Editor, as shown in Figure 12.3.

The Profile Set Editor consists of three tabs: one for managing profiles, one for editing pro-file entries, and one for changing your selection handler. Switch to the Select Handler tab andchange the value for Profile Selection Handler to Locale Selection Handler (press OK whenprompted that your profiles may be affected).

332 Chapter 12 Profiling Portlets

Page 370: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 12.3 The Profile Set Editor.

TIP

It is also possible to assign a value setter from the Select Handler tab. A value setterdynamically specifies profile entry values when the WebApp is generated (as opposed towhenever profile entries are edited). This is useful when you want to do a custom lookup orexecute some code to dynamically determine profile entry values. For example, you mightuse a value setter to display a different customer service phone number depending on thetime of day.

You are now using the Locale Selection Handler to resolve requests to your model withparticular profiles; however, you have not specified which profiles should map to which locales.To do this, switch to the Manage Profiles tab. You will see a list of profiles in the profile set; selectthe profile for US English and press the icon to open the Edit Profile dialog.

In the Edit Profile dialog, click the Advanced heading to open an interface for associatingparticular scenarios with this profile. These scenarios are called segments; in this case, each seg-ment corresponds to a particular locale. The list of segments on the left is the list of suggestionsfor locales that you can assign with the current profile, and it is populated through a class that isspecified in the configuration file for your current selection handler (Locale selection handler).The list on the right is the list of segments associated with the current profile.

Creating an Announcements Portlet 333

Page 371: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Select the segment en_US from the list on the left, and then press the > button to assign it tothe profile. Press OK when you are finished. The locale en_US is now associated with the USEnglish profile. When users run your application, a selection handler class works behind thescenes to map the user’s preferred locale (as specified in a request attribute) with a segment in oneof your profiles (to avoid ambiguity, you should never associate a particular segment with morethan one profile).

TIP

You can assign multiple segments to any given profile. A profile is used to provide a value fora builder input if the selection handler is able to match any of its segments to the appropriatevalue (a locale, for example).

Pressing the Add External button in the Edit Profile dialog enables you to specify seg-ments not provided in the Available for Association section of the dialog.

Edit the ES Spanish profile in the same way you did the English profile, only this time, addthe associated segment es_ES instead of en_US. Save the profile set when you are finished.

Placing Headings on the Page

The next step is to place the appropriate heading for each country and language combination atthe hrHeader and itHeader tags. To do this, first add a Text builder call to the model and name ithrHeader. Change the Page and Tag inputs to page1 and hrHeader, respectively, and then openthe Choose Reference dialog for the Text input. You should see an entry called LocaleData cre-ated by the Localized Resource builder. Through this, you can access the hrHeader property fromthe companyAnnouncements resource bundle. Select the hrHeader property as shown in Figure12.4 and press OK. This builder places the contents of the hrHeader property at the hrHeader tagon page1. Save the builder call when you are finished.

334 Chapter 12 Profiling Portlets

Figure 12.4 Selecting the hrHeader property.

Page 372: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Now add another Text builder call to the model, and this time name it itHeader. Specifypage1 and itHeader for the Page and Tag, respectively, and then for the Text input, select theitHeader property from the LocaleData section (after you select it, it should display in the buildercall as ${Variables/LocaleData/Data/announcements.itHeader}. Save the builder call when youare finished.

Adding English Announcements

The next step is to add the actual U.S. English announcements to the project. To do this, create anew folder under the WebContent/WEB-INF folder called chapter12, and then create a newXML file in the Chapter 12 directory called USEnglishAnnouncements.xml (both of theseactions can be performed from the Select a Wizard dialog, which you can open from the File,New, Other menu). Open the file and enter the following XML:

<?xml version=”1.0” encoding=”UTF-8”?>

<Announcements>

<HR>

<Item1>Please hand in your timesheets by close of business

tomorrow.</Item1>

<Item2>This Friday we will be raising money for Peter, who

would like some more money.</Item2>

</HR>

<IT>

<Item1>The portal server will be down for maintenance

between 5:00PM - 7:00PM Wednesday.</Item1>

<Item2>wpsadmin is having a baby!</Item2>

</IT>

</Announcements>

Notice that the announcements are split into two sections; the first section (HR) containsannouncements concerning the HR department and the second section (IT) relates to the ITdepartment. Save the file when you are finished.

Adding Spanish Announcements

Now add another XML file in the same directory; this time call it ESSpanishAnnounce-ments.xml. Open the file and enter the following XML:

<?xml version=”1.0” encoding=”UTF-8”?>

<Announcements>

<HR>

<Item1>Por favor entregen sus hojas the honorarios antes

de cierre de negocio mañana.</Item1>

<Item2>Este viernes acumularemos mas dinero para Peter,

quien quisiera más dinero.</Item2>

</HR>

Creating an Announcements Portlet 335

Page 373: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

<IT>

<Item1>El servidor del portal estara fuera de servicio

desde 5:00PM a 7:00PM este miércoles para mantenimiento.

</Item1>

<Item2>wpsadmin tendrá un bebe.</Item2>

</IT>

</Announcements>

This XML describes the ES Spanish version of the HR and IT announcements. Save the filewhen you are done editing it.

Importing the Announcements

Now that you have added announcements for US English and ES Spanish, you need to importthem into your model as an XML variable. To do this, add an Import to XML builder call to yourmodel and name it announcements. For the File Path, you need to specify the filename of theannouncements XML that you would like to use, which can change depending on the profile ofthe current user. To set this up, press the icon next to the File Path input to profile the File Pathinput. Make sure the Profile Set Name is set to localeValues, and leave the default Profile EntryName (Config_FilePath). For the profile values at the bottom of the dialog, enter the followingprofile value for the USEnglish and Default profiles:

/WEB-INF/chapter12/USEnglishAnnouncements.xml

For the ESSpanish profile, enter the value that follows:

/WEB-INF/chapter12/ESSpanishAnnouncements.xml

Press OK when you are finished. This profiles the File Path input using the profiles in thelocaleValues profile set. The announcements specified in the USEnglishAnnouncements.xml fileare used as the default (that is, if a match cannot be made against one of the other profiles). Youhave finished configuring the Import to XML builder, so save the builder call.

Displaying the Announcements

The final builder calls to add are the Data Pages, which you use to display the contents of theXML announcements to the hrNews and itNews tags. Add the first Data Page builder call to themodel and name it hrAnnouncements. Change the Page in Model input to page1, and thenchange the Page Type to View Only (you don’t need to enable users to edit the announcements).Expand the Created Element Settings section and change the Location for New Tags input tohrNews.

The final change to make to the first Data Page builder call is to specify the appropriatevariable in the Variable input. The variable you are after is the XML variable created by theannouncements Import to XML builder, so open the Choose Variable or Schema dialog for theVariable input (by pressing the ellipsis button to the right of it) and select the HR announcements,as shown in Figure 12.5. Press OK, and then save the builder call.

336 Chapter 12 Profiling Portlets

Page 374: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 12.5 Selecting the HR announcements.

Now, add another Data Page to the model, but this time, name it itAnnouncements. Asbefore, change the Page in Model input to page1 and the Page Type input to View Only. Changethe Location for New Tags input in the Created Element Settings section to itNews. For the Vari-able input, select the IT announcements from the same place you found the HR announcementsin the previous Data Page (after it is selected, it should display in the builder input as Variables/announcements/Announcements/IT). Save the builder call when you are finished.

You have now finished adding all of the builders you need for the companyAnnouncmentsportlet. In the next few steps, you will run a quick test of the model, and then implement someadditional profiling so that only the announcements for the department that the user belongs toare displayed.

Running a Preliminary Test

The easiest way to test a profiled portlet is to use the Applied Profiles view in the WPF Designer,which lets you preview the effect of a particular profile on your application. Select the AppliedProfiles view in the WPF Designer (if a tab for the Applied Profiles view is not already visible,you can open it from the under the WebSphere Portlet Factory heading in the Show View dialog,which you can open by selecting Show View, Other from the Window menu in your IDE). In theApplied Profiles view, select USEnglish for the Profile dropdown and press Apply. Then run yourmodel from the WPF Designer by clicking the icon on the toolbar. The company announce-ments should appear in English, as shown in Figure 12.6.

To test the Spanish profile, select Spanish for the Profile dropdown in the WPF Designer,and then press Apply. Run the model again, and you should see the company announcements inSpanish, as shown in Figure 12.7.

To test the Default profile, select Default for the Profile dropdown in the WPF Designer andpress Apply. When you run the model again, you will see the US English announcements dis-played (earlier you set these announcements to display by default).

Creating an Announcements Portlet 337

Page 375: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

338 Chapter 12 Profiling Portlets

Figure 12.6 Company announcements in English.

Figure 12.7 Company announcements in Spanish.

Testing the Selection Handler

Finally, you should test that the profiles work when the application is run without an explicit pro-file set in the Applied Profiles view. To do this, first turn off the explicit profile specified in theApplied Profiles view by closing the model and then reopening it. After this is done, you need toretest each profile.

To test the US English profile, make sure your current locale is set to en-US in your Webbrowser (the browser settings are used by the selection handler and are required now because noexplicit profile has been specified in the Applied Profiles View). To do this, first open the browsersettings for your Web browser (for example, in Internet Explorer, select Tools, Internet Optionsfrom the menu bar). Then open the language settings (you can do this in Internet Explorer bypressing the Languages button on the General tab) and make sure the first entry is en-US (add it ifthis is not the case). Run the companyAnnouncements model again, and you should see theannouncements in English.

Page 376: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

To test the Spanish profile, change the locale settings so that the first entry is es-ES. Youneed to close and reopen the browser again to see the changes. When the model loads, you shouldsee the company announcements in ES Spanish.

Finally, to test the Default profile, change the top locale entry to another region (such asaf-ZA), and rerun the model. The default profile should cause the US English announcements tobe displayed.

Profiling the hrHeader Based on Department

The final feature to add to the companyAnnouncements model is to restrict which announce-ments are displayed based on the user’s department (note that this will not affect the previous pro-filing you set up in the localeValues profile set). The department of the user will be taken from thegroup that the user belongs to in WebSphere Portal, so you need to add two groups to test with(one called HR and the other called IT), with a test user in each that you can use to log in and seewhether that user sees the appropriate announcements. The exact process you go through to setup these groups may differ depending on the version of WebSphere Portal you use and how youruser directory is configured; for example if you’re using an LDAP directory, you can set up thesegroups through an LDAP administration utility. If you are unsure how to add and configure portalgroups, consult your server documentation (or LDAP directory documentation if you’re using anLDAP directory) for instructions pertaining to your specific product version.

After you have set up a HR group and an IT group, you need to configure the displaybuilders in your model so that they are enabled or disabled depending on the department that thecurrent user belongs to. To do this, first open the hrHeader builder call, and expand the Propertiessection. Press the icon next to the Enable Builder input to open the Profile Input dialog. Youneed to configure this dialog to assign a value of true when the current user belongs to the HRgroup and false if the user belongs to the IT group. The profiles you use can’t be resolved usingthe Locale selection handler, so you need to create a new profile set to use a different selectionhandler. Press the Create Profile Set button to open the New Profile Set dialog, and name the pro-file set userDepartment. Change the Description to Enable builders based on depart-ment and press OK to save the new profile set.

The default profile entry (Text_BuilderCallEnabled) doesn’t need to be modified, but youneed to add two profiles so that the hrHeader builder can be disabled if the user belongs to the ITgroup, and it can be enabled if the user belongs to the HR group (leave the Default profile with thevalue true, so that by default the builder is enabled). For the first profile, press the Create Profilebutton and enter HR for the Profile Name. Press OK to add to the profile (the profile automaticallytakes its value from the Default profile). Now, press the Create Profile button again to create asecond profile, but name the profile IT. Press OK to add the profile, and then change the value ofthe profile to false. Press OK on the Profile Input dialog to accept your changes to the userDepart-ment profile set.

You have now profiled the hrHeader builder, so that it will not display the hrHeader if thecurrent user belongs to the IT group. Save your changes to the hrHeader builder call when you arefinished.

Creating an Announcements Portlet 339

Page 377: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Profiling the itHeader Based on Department

Now open the itHeader builder call, and press the icon next to the Enable Builder input toopen the Profile Input dialog for the Enable Builder input. You now need to configure this dialogto assign a value of true when the current user belongs to the IT group and false if the userbelongs to the HR group. You can use the same profile set created in the previous step, so makesure the userDepartment profile set is selected. The default settings for the Profile Input dialogwill be fine, except that you need to change the value for the HR profile to false. After you do this,press OK to accept the change to the profile set, and then save the builder call.

Profiling the hrAnnouncements Based on Department

Now that you have profiled the announcement headings, you need to profile the announcementsthemselves. To do this, first open the hrAnnouncements builder call, and as before, press the icon next to the Enable Builder input. You need to configure this dialog to assign a value of truewhen the current user belongs to the HR group and false if the user belongs to the IT group (asbefore, the default value is true, meaning that the HR announcements are displayed by default).Make sure the userDepartment profile set is selected, and change the value for the IT profile tofalse. Press OK to accept the change to the profile set, and then save the builder call.

Profiling the itAnnouncements Based on Department

The final input you need to profile is the Enable Builder input in the itAnnouncements buildercall, so open this builder call now and press the icon next to the Enable Builder input. Makesure the userDepartment profile set is selected, and then change the value for the HR profile tofalse (the other profiles should have a value of true). Press OK to accept the changes, and save thebuilder call when you are finished.

Configuring the userDepartment Profile Set

Now that you have configured all of your profiled inputs, you need to modify the userDepartmentprofile set so that it uses the WPS Group Segment selection handler. This selection handler mapsrequests to your model with the HR and IT profiles based on the user groups that you created ear-lier in the portal (namely, the HR and IT groups).

Open the userDepartment.pset file in the WebContent/WEB-INF/profiles directory, andswitch to the Select Handler tab. Change the Profile Selection Handler from Explicit Handler toWPS Group Segment Handler, and press OK when you are prompted that your profiles may beaffected. Now switch back to the Manage Profiles tab so that you can see a list of the profiles con-tained in the profile set. You need to modify the HR and IT profiles so that they are associatedwith the HR and IT groups in the portal. To do this, first select the HR profile and then click the

icon to edit the profile. Expand the Advanced section, and you will be given the option toassociate a particular WPS group with the HR profile. No suggestions are listed for the WPSGroup Segment handler; however, you can manually specify a WPS group by pressing the AddExternal button. On the dialog that follows, type HR and press OK. An entry for HR is added to

340 Chapter 12 Profiling Portlets

Page 378: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

the Associated box on the right of the Edit Profile dialog, which means the profile is now associ-ated with the HR group. Press OK to accept the changes.

The last change you need to make to the userDepartment profile set is to associate the ITgroup with the IT profile. Select the IT profile, and then press the icon to edit the profile. Pressthe Add External button under the Advanced section, enter IT, and press OK. An entry for IT isadded to the Associated box on the right of the Edit Profile dialog, which means that the profile isnow associated with the IT group. Press OK to accept the changes, and save the profile set whenyou are finished.

The companyAnnouncements portlet is now complete. The next section describes how youcan test this portlet from your IDE.

Testing the companyAnnouncements Portlet

To test the new profiling changes to the companyAnnouncements portlet, first open the AppliedProfiles view in your IDE and select HR for the userDepartment profile (you can leave the locale-Values profile as Default). This simulates what happens when you try to access the application asa member of the HR group. Run the companyAnnouncements model from your IDE, and youshould see that only the HR announcements are displayed, as shown in Figure 12.8.

Creating an Announcements Portlet 341

Figure 12.8 Testing the HR profile.

Return to your IDE and change the userDepartment profile to IT. Rerun the companyAn-nouncements model, and you should see the IT announcements displayed, as shown in Figure 12.9.

Figure 12.9 Testing the IT profile.

Page 379: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

342 Chapter 12 Profiling Portlets

After you have tested your model, you should test it in the portal so that you know theselection handler is correctly finding the user group and associating it with the correct profile. Todo this, first rebuild the application and add it to a page in the portal (for instructions on how to dothis, see the example in Chapter 1). Notice that the localeValues profile set is still in effect, sochanging your browser’s locale settings can still affect the language that the announcementsare displayed in. For example, if you try to access the portlet as a user who is a member of theHR group with the en-US locale setting in your browser, you should see the portlet shown inFigure 12.10.

Figure 12.10 The companyAnnouncements portlet.

After the portlet has been added to a page, log in to the portal first as a user who is a mem-ber of the HR group, and then as a user who is a member of the IT group. In the first case, youshould only see the HR announcements, and in the second case, you should see only the ITannouncements.

Summary

In this chapter, you learned how to customize a WPF application using profiling. The sampleportlet developed in this chapter utilized the default Locale Selection Handler and WPS GroupSegment Handler to customize company announcements depending on the locale and WPS groupof the current user. The knowledge gained in this chapter should give you a good foundation fromwhich to implement profiling in your other WPF applications, and to experiment with some of theother selection handlers available in WPF.

Chapter 13, “Using Ajax and Dojo,” describes how to use the Ajax capabilities of WPF toincrease the speed and interactivity of your portlets.

Important Points

• WPF portlets can cater to different types of requests using the profiling mechanism.

• Profiling settings are stored in profile sets. The profile sets in your application are kept in.pset files in the WEB-INF/profiles directory.

Page 380: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• A profiled input is an input in a builder that gets its value from a profile in a profile set.Profiled inputs have a blue icon next to them in the Model Editor.

• A profile entry is an individual point of variance in your application (such as a value fora particular builder input). A profile contains a series of profile entries, and the appropri-ate profile entry value is given to the appropriate builder input depending on certain con-ditions (for example, the locale or department of the current user).

• A selection handler is used to determine the profile that should be used for any givenrequest.

• You can remove profiling from a builder input by pressing the Remove Profiling buttonon the Profile Input dialog.

Important Points 343

Page 381: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 382: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

345

C H A P T E R 1 3

Using Ajax and Dojo

Ajax development techniques and the Dojo JavaScript toolkit provide rich client functionality toyour Web applications, improving interactivity between end users and your portlets and reducingloading times. The subject of this chapter is how you can use these technologies in WebSpherePortlet Factory (WPF). By the end of this chapter, you will have a firm grasp on the Ajax andDojo builders available, and you will also know how to use Dojo widgets that are not already partof the default Dojo builders. You will also have built a sample application to demonstrate thesetechniques, which displays key performance indicators for employees in a fictional organization.

Each of the files in this chapter is available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 13 folder (instructions for copying these files into yourproject are included in a readme.txt file in the same folder); however, to increase your under-standing of the topics discussed, it is recommended that you create these files yourself by follow-ing the example in this chapter.

The following topics are covered in this chapter:

• Using Ajax

• Creating a service provider

• Creating a performance portlet

• Using Dojo

Using Ajax

Reloading entire Web pages every time you want to interact with the server can be a time-consuming process, especially for your typical portal where there is a lot of code that needs toexecute when the portal displays (you generally want to update only a small portion of the pagefor each request). Ajax is a series of techniques that can be used to mitigate this issue by

Page 383: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

asynchronously communicating with backend servers while partially refreshing your portalpages (so you don’t have to continually reload the entire page). If you completed the example inChapter 11, “Field Validation, Formatting, and Translation,” you have already implicitly used oneof these techniques in the form of the Dynamic Validation builder, which dynamically runsclient/server validation routines.

CAUTION

It is important to note that when using Ajax in a portal environment, you cannot make portalAPI calls because Ajax calls effectively run outside the context of the portal server. So, ifyour pages contain any code that references portal URLs (when you use Property Brokercommunication, for example), then these regions cannot be loaded using Ajax. However,you can add Ajax to specific parts of the page by using the Ajax Region builder, whichenables partial page refreshing for all controls that fall within particular tags. Also, most ofthe WPF builders that can run actions from a UI component (for example, the Button andLink builders) contain a Post-Action Behavior section, which can be used to enable partialpage refreshing for that specific component. In the example in this chapter, you can seehow to use partial page refreshing to show and hide sections of the page without needingto reload it.

There are two other main ways you can use Ajax in WPF. The first is through one of theAjax-enabled builders (such as the Ajax Type-Ahead builder, which gives you a series of servercalculated prompts when typing text into a text input). The second is through the Dojo JavaScripttoolkit, which you can access if you add the Dojo Extension feature set to your project. Theexample in this chapter demonstrates how to use both of these techniques.

The first few sections of this chapter discuss how you can work Ajax capabilities into asimple key performance indicator (KPI) application. The final section of this chapter gives a briefintroduction to using the Dojo JavaScript toolkit in WPF, and then expands on the KPI exampleby introducing some more Ajax UI improvements via the Dojo builders.

Creating a Service Provider

In this section, you build a service provider model for retrieving a list of employee KPIs. Beforeyou proceed with this section, you need a WPF project to house the service provider model (aswell as the KPI model), so if you have a project from a previous chapter, you can use it. Other-wise, you should create a new WPF project (for more information on creating projects, see Chap-ter 1). In the “Using Dojo” section of this chapter, you add a feature set to the project so that youcan use the Dojo capabilities of WPF. The project will be published as a WAR file and deployedto a portal server, and you should also deploy the application to a local application server for test-ing (you can use the portal server if it runs on your local machine; otherwise, it is recommendedyou use the IBM WebSphere Application Server Community Edition server [WAS CE] thatcomes with WPF).

346 Chapter 13 Using Ajax and Dojo

Page 384: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

After you have a project set up, you need to add the service provider model. This modeluses the following builders to provide its functionalities:

• Service Definition

• Variable

• Simple Schema Generator

• Comment (x2)

• Method (x2)

• Service Operation (x2)

Creating a Model

Create a new model called performanceService in your project, under the folder WEB-INF/models/chapter13. Because you will be storing your data in an XML variable rather than get-ting it from a database, you need to create the service provider manually. To do this, the modelshould be based on the Empty template, which creates a model with no builder calls in it (formore information on creating models, see the example in Chapter 1).

Defining the Service

Add a Service Definition builder call to the model by selecting Service Definition from theBuilder Palette (you can open the Builder Palette by clicking the icon in Outline view) andpressing OK. Name the builder call performanceService, and expand the Testing Supportsection at the bottom of the builder call, and then enable the Add Testing Support option. WPFnow automaticallys generate test pages for the operations in your service every time the model isregenerated. Save the builder call when you are finished.

Adding Performance Data

The next step is to add your sample data for the service provider. Add a Variable builder call to themodel and name it performance. Change the Type input to XML and enter the following XMLinto the Initial Value input:

<RowSet>

<Row>

<Name>Dheeraj</Name>

<Area>Glenmore</Area>

<NewCustomers>0</NewCustomers>

<TotalSales>$17,000</TotalSales>

<FeedbackRating>70</FeedbackRating>

<Comments></Comments>

</Row>

Creating a Service Provider 347

Page 385: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

<Row>

<Name>Emilio</Name>

<Area>Parkdale</Area>

<NewCustomers>3</NewCustomers>

<TotalSales>$25,000</TotalSales>

<FeedbackRating>90</FeedbackRating>

<Comments></Comments>

</Row>

<Row>

<Name>Navin</Name>

<Area>Carrum</Area>

<NewCustomers>5</NewCustomers>

<TotalSales>$15,000</TotalSales>

<FeedbackRating>80</FeedbackRating>

<Comments></Comments>

</Row>

</RowSet>

After you’ve entered the information, save the builder call and then add a Simple SchemaGenerator builder call to the model. This builder call is used to automatically generate a schemabased on the Variable builder call, which is then used to define the structure of the result sets forthe Service Operation builder calls. Name the builder call performanceSchema, and for theSample Data input, select ‘performance’ from the drop-down list (this is the variable you createdearlier). Save the Simple Schema Generator builder call when you are finished.

Adding Functionality for Retrieving Performance Data

The next step is to specify functionality for the getPerformanceData operation, which retrieves alist of employee performance information based on a filter passed in to the operation (a filter con-sisting of an empty String (“”) returns all employee performance information). To do this, first adda Comment builder call to the model and name it getPerformanceData. This builder callmakes it easier to see which builders are specifically related to the getPerformanceData operation.

Next, you should add the method to run when the getPerformanceData operation is con-sumed. Add a Method builder call to the performance model, and name the Method getPerfor-manceData (there is no problem with this being the same name as your Service Operation). Addone argument for the Method in the Arguments input, called toGet of type String, and changethe return type of the builder call to IXml. The argument for this Method is a filter matching thevalue of a specified Area in the performance data, and the result returned from the Method is anIXml object taken from the performance data (and filtered according to the value of the toGetargument).

348 Chapter 13 Using Ajax and Dojo

Page 386: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

In the Method Body input of the builder call, enter the following code (note that you cancopy this code from the getPerformanceData Method.txt file, available for download from ibm-pressbooks.com/title/9780137134465, under the Chapter 13 folder):

{

try

{

//get performance Variable

IXml performance = webAppAccess.getVariables().getXml(“performance”);

//if toGet is blank, return all rows

if (toGet.equals(“”))

return performance;

//otherwise, iterate through each row and assemble an XML object

//consisting of the rows that match toGet

IXml result = XmlUtil.parseXml(“<Rowset></Rowset>”);

List theList = performance.getChildren(“Row”);

//for each entry in theList...

for (Iterator it = theList.iterator(); it.hasNext();)

{

IXml thisEntry = (IXml)it.next();

//check to see if the Area of the current entry equals toGet

if (thisEntry.findElement(“Area”).getText().equals(toGet))

{

//create a new XML entry in the result XML based on the values in

�thisEntry

IXml newEntry = result.addChildElement(“Row”);

newEntry.addChildWithText(“Name”,

thisEntry.findElement(“Name”).getText());

newEntry.addChildWithText(“Area”,

thisEntry.findElement(“Area”).getText());

newEntry.addChildWithText(“NewCustomers”,

thisEntry.findElement(“NewCustomers”).getText());

newEntry.addChildWithText(“TotalSales”,

thisEntry.findElement(“TotalSales”).getText());

newEntry.addChildWithText(“FeedbackRating”,

thisEntry.findElement(“FeedbackRating”).getText());

Creating a Service Provider 349

Page 387: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

newEntry.addChildWithText(“Comments”,

thisEntry.findElement(“Comments”).getText());

}

}

//return the result

return result;

}

//if there is an IOException, return null

catch (java.io.IOException e)

{

return null;

}

}

This code first gets a reference to the performance Variable, and then checks to see whetherthe toGet input is blank. If it is, then the performance Variable data is returned as is; otherwise, aresult set is constructed based on the employee area specified in the toGet input. First, an emptyXML document called result is created, and then a List of Row elements in the performance Vari-able is iterated through to find each employee with an area matching the area specified in thetoGet input. For each matching entry, a new row is added to the result variable based on the cur-rent row in the performance Variable. After the performance Variable has been iterated through,the result is returned to the caller. Finally, a catch block at the end of the code catches anyIOExceptions thrown by the parseXml command (for more information on error handling inWPF, see Chapter 14, “Error Handling, Logging, and Debugging”).

Save the builder call when you are finished.

Specifying the getPerformanceData Operation

Now you need to create the service operation to retrieve the performance data. Add a ServiceOperation builder call to the model, and make sure the Service Operation Properties section isexpanded. Select performanceService for the Data Service input, which links the operation to theperformanceService service created by the Service Definition builder call.

After this is done, change the Operation Name input to getPerformanceData, whichdefines how the operation is referred to by consumers. The Action To Call input defines what hap-pens when the operation is consumed; this input should be changed to point to your Method (get-PerformanceData). Make sure ‘Use structure from called action’ is selected for the InputStructure Handling input in the Operation Inputs section of the builder call. This specifies that theoperation will take its inputs from the getPerformanceData Method.

350 Chapter 13 Using Ajax and Dojo

Page 388: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Finally, expand the Operation Results section of the builder call, and select Specify ResultSchema for the Result Structure Handling input. This enables you to manually specify the struc-ture of the results to be returned from the operation. For the Result Field Mapping input, selectthe top element in the performanceSchema schema (RowSet). The RowSet element contains a setof performance data and is returned from the getPerformanceData Action List. The input shouldread performanceSchema/RowSet when you are finished. Make sure the Result Field Mappinginput is set to Automatic, which automatically maps results from the called action to the resultreturned from the service operation.

Save the builder call when you are finished.

Adding Functionality for Updating Performance Data

You now need to add functionality for updating the performance data, which is used to save com-ments entered through the UI. First, to organize the builders related to the update functionality inyour model, add a Comment builder call to the model and name it updatePerformanceData.Save the builder call when you are finished. The builders that follow this Comment are specifi-cally used to update performance data.

Add a Method builder call to the performance model, and name it updatePerformance-Data. Now add one argument for the Method called toUpdate of type String, and change thereturn type of the builder call to void. The argument for this Method is an IXml object represent-ing the new performance data used to update the existing performance data. No result needs to bereturned from the Method, as all that is required is that the backend XML data is updated.

Enter the following code into the Method Body input (you can copy this code from theupdatePerformanceData Method.txt file available for download from ibmpressbooks.com/title/9780137134465, under the Chapter 13 folder):

{

//get performance Variable

IXml performance = webAppAccess.getVariables().getXml(“performance”);

//get list Variables

List performanceList = performance.getChildren(“Row”);

List updateList = toUpdate.getChildren(“ins:Row”);

//iterate through updateList

for (Iterator uIt = updateList.iterator(); uIt.hasNext();)

{

IXml uEntry = (IXml)uIt.next();

//for each entry in updateList, iterate through performanceList

for (Iterator pIt = performanceList.iterator(); pIt.hasNext();)

{

Creating a Service Provider 351

Page 389: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

IXml pEntry = (IXml)pIt.next();

//check to see if the entries in updateList and performanceList have the

�same name

if (pEntry.findElement(“Name”).getText().equals(uEntry.findElement

�(“Name”).getText()))

{

//update the comments in the current entry for performanceList

pEntry.findElement(“Comments”).setText(uEntry.findElement(“Comments”).getText());

}

}

}

//set performance variable

webAppAccess.getVariables().setXml(“performance”, performance);

}

As with the previous Method, this code begins by getting a reference to the performanceVariable. Two lists are then created: the first (performanceList) iterates through the rows in theperformance XML, and the second (updateList) iterates through the rows in the toUpdate argu-ment passed to the Method. Note that the Row element for the toUpdate Method has the prefix‘ins:’—this prefix is added to each element as it is passed to the service operation from the DataPage, so you need to use it in the previous code to locate elements in the toUpdate Variable. TheupdateList is then iterated through, and for each row in the updateList, a corresponding row(matching on the Name) is found in the performanceList. After it is found, the comments in therow in the performanceList are updated with the comments in the updateList. At the end of theMethod, the performance XML data inside the Method is written to the WPF performance Vari-able, so that it is accessible via the getPerformanceData operation (note that the performanceXML data inside the Method is updated whenever the setText method is run).

Save the builder call when you’ve finished editing it.

Specifying the updatePerformanceData Operation

As before, you now need to create a service operation to surface the functionality you just created.To do this, add a Service Operation builder call to the model, and then select performanceServicefor the Data Service input to link the operation to the performanceService service. Change theOperation Name input to updatePerformanceData, which defines how the operation isreferred to by consumers. For the Action To Call input, select your update Method (updatePerfor-manceData).

Because the input to the updatePerformanceData Method is an IXml object, you need tospecify the schema of the object in the Operation Inputs section. First, select Specify inputschema for the Input Structure Handling input; then in the Input Schema input, select the Rowset

352 Chapter 13 Using Ajax and Dojo

Page 390: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

of the performanceSchema schema (performanceSchema/RowSet). After you have done this,change the Result Structure Handling input in the Operation Results section to ‘No results’, asthe operation does not return a value. Save the builder call when you are finished.

Your performance service is now ready. The next section walks you through the process oftesting this model from your IDE.

Testing the Service Provider

Because you enabled testing support for the service provider, WPF automatically generates testpages for it. This enables you to test the service provider directly from the IDE.

To test the service, run the performanceService model from the WPF Designer by clickingthe icon on the toolbar. This runs the performanceService model with the last run configura-tion you used. If you have not set up a run configuration before, you are prompted to do so—create a new configuration under the WebSphere Portlet Factory Model category (if you wantmore information on setting up a run configuration, see the “Testing the Application” section inChapter 1).

After you run performanceService, you should see the index test page in your default Webbrowser, as shown in Figure 13.1. This screen lists all the operations available on the perfor-manceService service (it should display only one for getPerformanceData).

Testing the Service Provider 353

Figure 13.1 Index test page from the performanceService model.

Testing the getPerformanceData Operation

To test the getPerformanceData operation, click the getPerformanceData link. A new page loads,requesting the value of the toGet Variable. To test that all results can be retrieved, leave the toGetfield blank and press the Submit button. You should see the full table of performance data, asshown in Figure 13.2. After you have done this, run the test again, but this time, try specifying thearea for a particular employee (say, for example, Glenmore). After you press Submit, you shouldsee only the results for that area (for Glenmore, you would see Dheeraj’s results).

Note that you can’t actually test the updatePerformanceData operation from the service, asit requires an XML argument (which you can’t specify in the default testing interface). Instead,you will test the update feature through the performance portlet in the next section.

Page 391: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

354 Chapter 13 Using Ajax and Dojo

Figure 13.2 Testing the getPerformanceData operation.

You now have a service provider called performanceService. The next section walks youthrough creating a service consumer model to display the performance data to the screen, andmanipulate this display using Ajax.

Creating a Performance Portlet

This section describes how to add a second model to your project, a service consumer that dis-plays a user interface for accessing KPI information from the performanceService service. Thismodel uses some of the Ajax capabilities of WPF, and is surfaced to a portal server as a portlet(for more information on the service consumer/provider pattern in WPF, see Chapter 2, “Provid-ing and Consuming Services”). Later in this chapter, Figure 13.6 shows a screenshot of the port-let using the builders added in this section.

In this section, you create a service consumer model using the following builders:

• Action List (x3)

• Page

• Portlet Adapter

• Service Consumer

• Data Page

• Check Box

• Visibility Setter (x2)

• HTML Event Action

• Ajax Type Ahead

• Text Input

• Button

Creating a Model

Create a new model called performance in your project, under the folder WEB-INF/models/chapter13. Although you can use the List and Detail Service Consumer option in this example(even though you don’t have any detail data), it is easier to base the model on the Main and Pagetemplate, using a Page Type of Simple Page. For more information on creating models, see theexample in Chapter 1. The reason for this is that you need a form element on the page to use theCheck Box builder, which WPF does not automatically create if you don’t specify any detail data(because it thinks that you are just displaying data on the screen). Rather than trying to manuallyadd a form element to the page, it is easier to create the list yourself using a Data Page.

Page 392: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Performance Portlet 355

After it is created, your model should have two builders in it: an Action List called mainand a Page called page1. The Action List runs automatically whenever the model is run and opensthe page1 Page.

Modifying the Page

Open the Page builder, and change the contents of the Page Contents (HTML) input to the HTMLlisted in the following:

<html>

<body>

<form name=”performanceForm” method=”post”>

<div align=”center”>

<div style=”font:12pt Arial;font-weight: bold;color:

#336699;”>Key Performance Indicators</div>

<br>

<br>

<span name=”performanceDisplay”></span>

<br>

Show area: <span name=”areaSelect”></span>

<span name=”submitButton”></span>

<br>

<br>

<span name=”feedbackCheckbox”></span>

</div>

</form>

</body>

</html>

The HTML contains several span tags that will be replaced later in this section usingbuilders in WPF: The first (performanceDisplay) is for the table of performance data, and the sec-ond (areaSelect) is for a text box where users can select a specific area to display in the perfor-mance table. The third span tag (submitButton) is for a button that will be used to apply the areaspecified in the areaSelect text box, and the final span tag (feedbackCheckbox) will be replacedwith a checkbox used to toggle whether one of the columns in the performance table is visible.Save the builder call when you’ve finished entering the contents of the Page Contents (HTML)input.

Adding a Portlet Adapter

The first builder call to add to the performance model is a Portlet Adapter builder call, which sur-faces the model as a portlet on the portal server specified in your deployment configuration. Adda Portlet Adapter builder call to the model, and then change the Name to performance. Then,

Page 393: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

change the Portlet Title to Performance and the Portlet Description to This portlet dis-plays information on KPIs. This surfaces your model to the portal server as a portlet calledPerformance. Save the builder call when you are finished.

Consuming the Service

Add a Service Consumer builder call to the model. You use this model to access the getPerfor-manceData operation in the performanceService service. Change the name of the builder call toperformance, and then specify the location of the provider in the Provider Model input(chapter13/performanceService). Save the builder call when you are finished.

Because you want the getPerformanceData operation to run every time you open the model(this causes the performance data to be displayed on the screen without the user having to manu-ally click on anything inside the portlet), you should add a line into the main Action List to con-sume the getPerformanceData operation. Because this operation takes an argument, you shouldalso add a line to set the argument to an empty String so that all the performance data isdisplayed.

TIP

You don’t necessarily need two separate actions to call an operation that requires argu-ments. One way to specify only a single action is to use the WithArgs method for your oper-ation (for example, performanceGetPerformanceDataWithArgs). Specifying two separateactions can, however, make your Action Lists easier to read and maintain.

You should set the argument before you call the operation, so for the first action, open themain Action List, and then insert a line before the page1 action (you can do this by right-clickingthe page1 action and selecting Insert). Then, open the Select Action dialog for the new action (byclicking the Ellipsis icon to the right of the new row) and select Special, Assignment. Thisenables you to assign a source value to a target Variable. You can leave the Source field blank (asyou want to assign an empty String), and for the Target field, open the Variables dialog and thenselect the toGet argument for the getPerformanceData operation, as shown in Figure 13.3. PressOK when you are finished to add the action.

For the next action, insert another line before the page1 action, and then change it to read asshown in the following:

DataServices/performance/getPerformanceData

Note that you don’t have to type this action directly, as you can select it from the DataSer-vices category in the Select Action dialog available from the ellipsis button to the right of theaction. After you add the new action, your Action List will retrieve all employee performancedata via the getPerformanceData operation. Save the Service Operation when you are finished.

356 Chapter 13 Using Ajax and Dojo

Page 394: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Performance Portlet 357

Figure 13.3 Selecting the toGet argument.

Displaying the Interface

Now add a Data Page builder call to the model (for more information on the use of the Data Pagebuilder, see Chapter 3, “Using Data from a Relational Data Source”). The purpose of this DataPage is to show the results of the getPerformance operation on the screen. Name the Data PagedisplayPerformance and change the Variable input to the results retrieved from the getPerfor-mance service (DataServices/performance/getPerformanceData/results). Then, change the Pagein Model input to page1, and the Location for New Tags input to performanceDisplay, so that theresults of the builder are displayed at the performanceDisplay tag on page1. Save the builder callwhen you are finished.

Hiding and Showing a Column Using Ajax

In this example, you hide and show the feedback rating column in the performance data, based onwhether the user has enabled a checkbox on the screen. To do this, first add a Variable builder callto the model and name it feedbackCheckboxValue. This variable will hold the value of thecheckbox that will be used to toggle whether the feedback rating column is displayed (if youdon’t use a variable, then the value of the checkbox will be lost whenever the page is submitted).Change the Type of the Variable to Boolean and the Initial Value to true (so that the feedbackcolumn is displayed by default), and then save the builder call.

Now add a Check Box builder call to the model, and name it feedbackCheckbox. Specifythe Page input as page1 and the Tag input as feedbackCheckbox, which will place a checkbox onthe feedbackCheckbox tag on page1. Change the label input to Show feedback rating, which

Page 395: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

will be the text displayed next to the checkbox, and then change the Default value to the feed-backCheckboxValue Variable (you can do this by selecting feedbackCheckboxValue from theVariables section of the Choose Reference dialog). This causes the value of the checkbox (that is,whether it is enabled or not) to be taken from the feedbackCheckboxValue Variable. Save thebuilder call when you are finished.

The next change is to actually hide the feedback rating data and the feedback column head-ing when the feedbackCheckbox checkbox is enabled. To do this, add a Visibility Setter buildercall to the model. Call it hideFeedback and change the Page input to page1, and then changethe Tag input to FeedbackRating. Change the Visibility Rule to ‘Hide when Value is “false” or“hide”’, and specify the Value as the value of the feedbackCheckboxValue Variable (after youhave selected the Variable value from the Choose Reference dialog, it should display as${Variables/feedbackCheckboxValue} in the Value input). This causes the contents of the Feed-backRating tag (that is, the column of feedback ratings) to be hidden when the checkbox isunchecked.

Save the builder call, and make a copy of the builder call in the same model. Change thename of the builder call to hideFeedbackHeader and the Tag to FeedbackRatingHeader. Thiscauses the heading for the feedback column to be hidden when the checkbox is set to false. Savethe builder call when you are finished.

Responding to a Change in the Checkbox Value

You now need to define what happens when the user toggles the checkbox on or off. In this case,you need to set the value of the feedbackCheckboxValue Variable to whatever the feed-backCheckbox value is, and then reload the page. To do this, add an Action List to the model andcall it changeFeedbackCheckboxValue. Leave the Return Type as Object, and then open theSelect Action dialog for the first action in the Actions input. Select Assignment from under theSpecial category, which enables you to assign a source value to a particular target. For the Target,select the feedbackCheckboxValue Variable (it then displays in the Target field as Variables/feedbackCheckboxValue), and for the Source, select the value of the checkbox from under theInputs section of the Choose Reference dialog (it then displays in the Source field as ${Inputs/feedbackCheckbox}). Press OK when you are finished, and the action is added to the Action List.Add a second action underneath the first by selecting page1 for the second row in the Actionsinput, which refreshes the page after the feedbackCheckboxValue Variable has been set. Save thebuilder call when you are finished.

Now add an HTML Event Action builder call to the model. The HTML Event Action canbe used to intercept a particular HTML event (such as the onChange event of the checkbox) andexecute a particular action when that event occurs (any original actions attached to that event areoverwritten). Change the name of the builder call to feedbackCheckboxChange, and thenspecify the Page as page1 and the Tag as feedbackCheckbox. For the Event Name, selectonChange, and for the Action input, select the Action you just created from the Select Action dia-log (that is, changeFeedbackCheckboxValue). This causes the changeFeedbackCheckboxValueaction to run every time the checkbox is checked or unchecked. Also, make sure the Action Type

358 Chapter 13 Using Ajax and Dojo

Page 396: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

is set to ‘Submit form and invoke action’, as this ensures that the form is submitted when theevent is triggered, and that the Visibility Setters are therefore able to update the feedback column.

One final change to make to this builder is to make sure that the entire page is not reloadedafter the changeFeedbackCheckboxValue action is run. To do this, expand the Post-ActionBehavior section, and change the Post-Action Behavior input to ‘Refresh specified page locationafter running action’. Some more inputs display underneath, which correspond to the section ofthe page that you need to refresh after the action is run. Change the Page input to page1 and theTag input to performanceDisplay (this is where the performance data is displayed), and save thebuilder call. This causes the performanceDisplay section of page1 to be refreshed after thechangeFeedbackCheckboxValue action executes.

Adding an Area Select Field

The next builder adds a text input box to the areaSelect tag, enabling users to specify an area theywould like to use for filtering the performance data. Add a Text Input builder call to the model andname it areaSelectField. In the Page Location section, change the Page to page1 and the Tagto areaSelect. Leave the other fields with their default values and save the builder call (note thatleaving the Text input blank causes the text input to be blank when the page first loads).

Adding Submit Functionality

Now, you need to add a button to the page so that users can apply the filter specified in the areaselect field. To do this, first add an Action List builder call to the model and name it submitAc-tion. This Action List defines the sequence of actions to execute when the button is clicked.Make sure the Return Type is Object, as the final action in the list displays the contents of page1.You need three actions for this Action List. The first assigns the value of the areaSelect input tothe toGet argument of the getPerformanceData operation; the second executes the getPerfor-manceData operation; and the final action displays page1.

Open the Select Action dialog for the first row in the Actions input, and select Assignmentfrom the Special category. As you did in the main Action List earlier, you should then select thetoGet argument for the Target field from the Data Services section of the Variables dialog. For theSource input, select the areaSelect input from under the Inputs category in the Choose Referencedialog and press OK. This action takes the value of the areaSelect text input and assigns it to thetoGet argument.

For the second action, execute the getPerformanceData operation as you did in the mainAction List (it should display in the list as DataServices/performance/getPerformanceData).Finally, the third action should load page1, so select page1 from the Pages section of the SelectAction dialog on the third row. Save the builder call when you are finished.

Now that you have an Action List handling the submit functionality, you need a button toenable users to execute this functionality. Add a Button builder call to the model and name itsubmitButton. In the Page Location section of the builder call, specify page1 and submitBut-ton as the Page and Tag, respectively, which places the button just to the right of the area selecttext input. Type Submit for the Label, and for the Action, specify submitAction (make sure the

Creating a Performance Portlet 359

Page 397: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Action Type input is set to Submit form and invoke action). The final change to make to this but-ton is to ensure that the page is partially refreshed after the button is pushed (so that the entireportal page does not have to be reloaded). To do this, change the Post-Action Behavior input inthe Post-Action Behavior section to ‘Refresh specified page location after running action’. Then,change the Page input to page1 and the Tag input to performanceDisplay (this is where the per-formance data is displayed). This ensures that only the performanceDisplay section of page1needs to be refreshed. Save the builder call when you are finished.

Adding Ajax Type Ahead

The next step is to add Ajax Type-Ahead capabilities to the area select field in the performancedata. This enables users to select an area without necessarily having to type the entire name of thearea. To do this, add an Ajax Type-Ahead builder call to the model, and change the Name toareaSelectTypeAhead. Specify the Page as page1 and the Tag as areaSelect, and then enterthe following values into the Values input:

Parkdale,Glenmore,Carrum

The default behavior for the Ajax Type-Ahead builder is that whenever a user enters in avalue where the first letter matches one of the first letters specified in the Values input, the match-ing element from the Values input displays as a suggestion for the user (which they can select anduse as the new value if they wish). Notice that you can also obtain these values from a lookuptable if you wish (which you would create using a Lookup Table builder). An example using theLookup Table builder is given in Chapter 16, “More Techniques for Domino.” Also, note that atthe bottom of the builder call you have options to change the way the suggestion prompts are fil-tered, and you can also change how many suggestions display at one time.

In the current example, it is more useful if all of the type-ahead values are displayed atonce, so change the Filter mode input to ‘Show all values’. Save the builder call when you havefinished configuring it.

Your service consumer model is now ready to test and deploy to a portal server, which iscovered in the next section.

Testing the Performance Portlet

Make sure the performance model is the currently active model in your IDE, and then run the per-formance model from the WPF Designer. The performance data should display in your defaultWeb browser, as shown in Figure 13.4. Note that this data displays by default because there is anaction in the main Action List to consume the getPerformanceData operation (passing in anempty String for the toGet argument).

Notice that by default, the Show feedback rating checkbox is enabled, which means that thefeedback column is displayed. Disable the checkbox, and you should see that the feedback col-umn is removed (the entire column should disappear). If you have configured the Post-ActionBehavior section correctly, then this is done without reloading the page. You can check if the page

360 Chapter 13 Using Ajax and Dojo

Page 398: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

has reloaded by looking at the Back button on your browser. If there is no page to go back to, thenthe column was updated without actually reloading the page. Of course, the difference inresponse time is not as noticeable now because the model is being viewed by itself, but in the con-text of the portal, the increase in response time should be immediately obvious (particularly onpages with multiple portlets).

Testing the Performance Portlet 361

Figure 13.4 Testing the display of performance data.

To test the area select functionality, type a character into the area select field. You shouldnotice that a box of suggestions is now displayed underneath the text input (as shown in Figure13.5). Click one of these entries (say, for example, Carrum) and it will populate the area selecttext input with the appropriate value. After you press the Submit button, the performance datashould refresh so that only employees working in the area specified are displayed (so onlyNavin’s details are displayed for Carrum, for example).

Figure 13.5 Ajax Type-Ahead for the area select field.

After you have done this, remove the contents of the areaSelect input and press the Submitbutton again. The performance data should reload, displaying performance data for everyemployee.

Close the performance model when you’ve finished testing it. You should now rebuild yourapplication on the portal server (for instructions on how to do this, see the example in Chapter 1),after which you will be able to view the performance model as a portlet. After you have added theportlet to a page in the portal, it should display as shown in Figure 13.6. Note that when you clickon the checkbox, it updates the feedback column without updating the rest of the portal page.

Page 399: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

362 Chapter 13 Using Ajax and Dojo

Figure 13.6 The Performance portlet.

Using Dojo

Dojo is a JavaScript toolkit that can be used to add powerful UI capabilities to Web applications.When you add the Dojo Extension feature set to a WPF project, a library of JavaScript widgets isadded to your project (in WPF 6.0.2, these widgets are added under the WebContent/factory/dojofolder), which you can then use in your portlets. WPF 6.0.2 comes with version 0.4 of the Dojotoolkit, which contains interface improvements from dialog boxes to drag-drop functions, and itis worthwhile having a browse through the Dojo libraries to see if there is anything that might beable to improve the UI of your portlets. You can find out more about the Dojo toolkit on the Dojohome page at http://dojotoolkit.org/).

There are two ways to use Dojo in WPF: One is to use the default WPF builders, and theother is to access the Dojo library directly (which you can do from HTML, JavaScript, and evenother builders). To use the Dojo builders, you simply need to add the builder to your project asyou would any other builder—you don’t need to be concerned with how the functionality isimplemented. If you access the Dojo libraries directly, however, you do need some knowledge ofthem (at minimum, you need to know what to call and how to call it). In this second scenario, youalso need to add a Dojo Enable builder call to your model, which primes your application to usecertain Dojo features. The example in this section uses both of these techniques.

One caveat worth mentioning with regard to Dojo (and, indeed, with Ajax in general) is thatyour applications can become sluggish if you have an abundance of UI controls that constantlyupdate the server. This is particularly true if you have users who communicate with your portalover a slow connection. As a general precaution, then, it is recommended that these componentsare used sparingly.

The rest of this section walks you through the process of adding some useful Dojo func-tions to the performance portlet built earlier in the chapter. The following builders are used:

Page 400: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• Comment

• Action List (x2)

• Dojo Inline Edit

• Dojo Tooltip

• Dojo Enable

• Attribute Setter

A screen shot of the final portlet is shown later in Figure 13.14.

Enabling Dojo Capabilities

Before the Dojo libraries are even available in your WPF project, you need to make sure you’reusing the Dojo Extension feature set. To do this, select Project, Properties from the menu bar inthe WPF Designer, and then open the WebSphere Portlet Factory Project Properties, Feature Infosection. On the Feature Info page, enable the box for the Dojo Extension (found under the DojoAjax category; alternatively, you can also just enable the Dojo Ajax category) and press OK.When prompted whether you would like to deploy, select ‘No’, as you can rebuild your project atthe end of this section. You should now notice a new folder under the WebContent/factory direc-tory called dojo, and if you open the Builder Palette, you can also see several new builders (allbeginning with the prefix Dojo).

Before you proceed with this section, add a Comment builder call to the model and name itDojo builders. Save the builder call. This builder call will serve as an organizational dividebetween the builders in the previous section of the chapter and the builders in this section.

Adding an Action to Save Comments

A number of actions need to be executed whenever users save a comment. First, the toUpdateargument of the updatePerformanceData operation needs to be set, after which the updatePerfor-manceData operation needs to be called. Finally, page1 needs to be redisplayed (the form will besubmitted when a user tries to save a comment, so if you don’t redisplay page1, no output will beproduced).

Add an Action List builder call to the model. Change the name of the Action List tosaveComment, and make sure the Return Type is set to Object. For the first action in the Actionsinput, open the Select Action dialog and select Assignment from the Special category. The Sourcevariable in this case should be the RowSet of the argument to the updatePerformanceData opera-tion, as shown in the Variable dialog in Figure 13.7.

For the Target value, select the data used in your data page—that is, the results from thegetPerformanceData operation (as shown in Figure 13.8). This data holds the values of the cur-rent data in the performance table, including any new comments added by the user. Press OKwhen you are finished. The toUpdate argument is now set to the performance data displayed onthe screen, so that this data can be updated by the updatePerformanceData operation.

Using Dojo 363

Page 401: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

364 Chapter 13 Using Ajax and Dojo

Figure 13.7 Selecting a Source variable.

Figure 13.8 Selecting a Target value.

The next action to add will run the updatePerformanceData operation, so open the SelectAction dialog and select the updatePerformanceData operation from the DataServices section (itshould then display in your Action List as DataServices/performance/updatePerformanceData).For the third action, select page1. Save the builder call when you are finished. You will call thisAction List in the next step, where you add inline edit capabilities to the comments column.

Page 402: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Inline Edit Capabilities

To add inline edit capabilities to the Comments column in the performance table, add a DojoInline Edit builder call to the model and name it inlineEdit. This builder adds a small Pencilicon next to a set of tags on the page, which display text input boxes when clicked. This mecha-nism can be used to dynamically change the values of cells in a table created by a Data Page.

The Dojo Inline Edit builder provides a number of customization features (for example tochange the graphics used for the icons), but in most cases, the default settings are fine. You do,however, need to change the Fields input to tell the builder which fields should receive the Pencilicon. To do this, click the ellipsis button next to the Fields input to bring up the Data Page FieldChooser dialog, and then select the Comments column from the displayPerformance Data Page,as shown in Figure 13.9. Press OK when you are finished.

Using Dojo 365

Figure 13.9 Selecting the Comments column.

To run the saveComment Action List every time a new comment is added, enable the Sub-mit Form input, and then enter saveComment in the Action input that displays. Save the buildercall when you are finished.

If you run your application at this point, you should see the Pencil icon display next toeach cell in the Comments column. When you click on the Pencil icon for a particular row, youcan add comments for that person, as shown in Figure 13.10.

Page 403: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

366 Chapter 13 Using Ajax and Dojo

Figure 13.10 Editing a comment.

Adding Tooltips

In this section, you add a tooltip to the FeedbackRating column, so that users will know what thecolumn values mean when they move the mouse cursor over the column. To do this, add a DojoTooltip builder call to the model and name it feedbackTooltip. For the Page Location, specifythe Page as page1 and the Tag as FeedbackRating. By default, this places the tooltip hotspot atthis location, but it may also collide with any other Dojo controls you decide to add to the Feed-backRating column later. To avoid this, you should change the Location Technique to ‘Relative toNamed Tag’, and then specify Wrapper for the Placement input and feedbackTooltip for the NewTag Name. Although your tooltips will work with the default placement, the Wrapper placementis preferable in that it does not replace the underlying tag you are applying the tooltip to.

The Tooltip Type input enables you to either show a line of text or run a particular actionwhen the cursor is over the tooltip hotspot. In this example, you use a combination of both tech-niques to display the feedback rating and some surrounding text. To do this, first make sure Textis selected, then type Feedback score is out of 100 into the Tooltip Text input. Then placethe cursor just before the word out in this text, and open up the Choose Reference dialog. Fromthe Variables category, select the current row’s feedback rating as shown in Figure 13.11 andpress OK.

Add a space after the feedback rating, so that the Tooltip Text now appears as:

Feedback score is ${Variables/RowLoopVar/Row/FeedbackRating}

out of 100

Save the builder call when you are finished. If you test the model at this point and move the mouse cursor over the FeedbackRating col-

umn, you should see a tooltip pop up as shown in Figure 13.12.

Page 404: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Using Dojo 367

Figure 13.11 Selecting the current row’s feedback rating.

Figure 13.12 Feedback tooltip.

Adding a Feedback Bar

The final Dojo modification in this chapter is the modification of the feedback rating column todisplay a graphical representation of the feedback rating. The bar is created using the dojo.widget.ProgressBar widget in the Dojo toolkit. Because there are no Dojo builders that providethis functionality by default, you need to first load the appropriate widget into your model (using

Page 405: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

the Dojo Enable builder), and then overwrite an element on the page for the result (which you cando using the Attribute Setter builder). Note that the other Dojo builders in WPF implicitly use aDojo Enable builder behind the scenes to get access to the appropriate Dojo libraries.

First, add a Dojo Enable builder call to the model and name it dojoEnable. The DojoEnable builder loads any Dojo widget packages specified in the Requires Package List so thatthey are accessible in your model. In this case, you need only the ProgressBar widget, so typedojo.widget.ProgressBar in the Requires Package List input and save the builder call. Notethat you can also specify JavaScript in the JavaScript input or inside a .js file in the JavaScriptFiles input; these scripts are then added to the target page. You might use specific scripts here ifyou want to do things such as add a Dojo dialog box to the page (for example, you can define thebox and its properties). In this example, leave the inputs blank.

The final change to make to the model is to add an Attribute Setter builder call. Do this now,and change the name of the builder call to addPerformanceBar. This builder call is used toreplace the contents of the new Feedback Bar column with Dojo widgets, which you can config-ure inside the Attribute Setter (you can also add these widgets at any place in the model whereyou can specify HTML, but it is easier and more common to use an Attribute Setter for thispurpose).

Change the Page input of the builder call to page1, and change the Tag input to Feedback-Rating. As with the Dojo Tooltip, you should create a wrapper for the tag rather than replace it, sochange the Location Technique to ‘Relative to Named Tag’, the Placement input to Wrapper, andthe New Tag Name to FeedbackBar. After this is done, fill in the Attribute List section of thebuilder call, as shown in Figure 13.13.

368 Chapter 13 Using Ajax and Dojo

Figure 13.13 Configuring the Attribute Setter.

Notice that several different attributes have been added to each entry in the FeedbackRatingcolumn (at the FeedbackBar tag), and these attributes specify properties for the Dojo Progress-Bar. The dojoType input specifies that the widget should be a ProgressBar (you don’t need tospecify the full package name for this attribute), and the progressValue is used to set the current

Page 406: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

value of the bar. Note that in the example, this value is taken from the FeedbackRating on the cur-rent row, which is provided through the RowLoopVar variable. The maxProgressValue attributedefines the maximum value for the bar (in this case, it is 100) and the width and height define thedimensions of the bar in pixels.

Save the builder call when you are finished. Test the model from your IDE, and you should see that a feedback bar is displayed for each

person, as shown in Figure 13.14. Note that the tooltip still works with the feedback bar, and youcan also hide and show the feedback bar by toggling the ‘Show feedback rating’ checkbox.

Important Points 369

Figure 13.14 The performance model with feedback bar.

Summary

In this chapter, you learned how to use Ajax to improve the usability and responsiveness of yourWPF applications. You also learned about the strengths and limitations of Ajax in WPF, and howyou can use the Dojo JavaScript toolkit to further enhance your WPF portlets. You also created anexample portlet that demonstrates some of these techniques and that displayed a table ofemployee key performance indicators.

Chapter 14, “Error Handling, Logging, and Debugging,” discusses how to enhance yourWPF development with builders that provide error handling, logging, and debugging capabilities.

Important Points

• Most builders that can run an action from a UI component contain a Post-Action Behav-ior section, which can be used to enable partial page refreshing for a UI control.

• The Ajax Region builder can be used to turn on partial page refreshing between certaintags on the page. Sections of the page that contain portal URLs cannot be displayedusing Ajax because Ajax code essentially runs outside the context of the portal.

Page 407: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• The Ajax Type Ahead builder can be used to prompt users with several suggestions for atext input.

• The Dojo JavaScript toolkit can be used in WPF by enabling the Dojo Extension featureset. Adding a Dojo Enable builder call to your model lets you access any of the Dojowidgets in the Dojo 0.4 library.

• The Dojo Tooltip builder enables you to pop up context-sensitive text or actions at a par-ticular page control.

• The Dojo Inline Edit builder adds an edit control inside a data page field, which is usefulfor inline editing of table columns.

370 Chapter 13 Using Ajax and Dojo

Page 408: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

371

C H A P T E R 1 4

Error Handling,Logging, andDebugging Portlets

Error handling, logging, and debugging are important aspects of the portlet development process,and can increase the reliability and overall quality of your applications. This chapter explainshow to work these elements into your WebSphere Portlet Factory (WPF) applications, using acombination of Eclipse, log4j, and the default WPF builders. By the end of this chapter, you willhave a good understanding of the different error handling, debugging, and logging techniquesavailable in WPF. You will also create a sample application that applies some of these techniquesto make the application more robust.

The files discussed in this chapter are available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 14 folder (instructions for copying these files into yourproject are included in a readme.txt file in the same folder); however, to increase your under-standing of the topics discussed, it is recommended that you create these files yourself by follow-ing the example in this chapter.

Note that this chapter does not discuss non-WPF techniques of error handling, logging, ordebugging (such as JUnit).

The following topics are covered in this chapter:

• Error handling

• Debugging

• Logging

Error Handling

Typically, there are two types of errors that can occur in a WPF application: errors that occur atcompile time and errors (or exceptions) that occur at runtime (note that the word ‘runtime’ is usedbroadly here to mean an error that occurs when the application is run, and does not specifically

Page 409: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

refer to the collection of Java exceptions that inherit from the RuntimeException class). Compiletime errors show up in the Problems view (marked with an icon) and should be addressedbefore deploying your application, as models with compile-time errors may behave unpre-dictably when run. There are some (albeit rare) scenarios in which you may decide not to addresscompile-time errors (for example, when your model accesses a JAR file that doesn’t exist on thecompile time classpath), but as a best practice, you should always eliminate errors before runningyour application (in the case of the example just mentioned, then, you might add the JAR to theclasspath used in the WPF Designer, and then exclude it from being deployed so that it doesn’tconflict with the same JAR on the portal server).

In trying to handle scenarios where errors occur after you have executed your application,the main technique used in Java development is the try/catch mechanism. A basic try/catch blocklooks similar to the following:

try

{

//some code that might cause an exception to be raised

}

catch (SomeExceptionClass e)

{

//code to handle exception

}

The code in the try block will run, and if an exception is raised for which there is a catchblock (such as the SomeExceptionClass exception), then the code in the catch block runs. If thereis no block to catch the exception, then it is thrown back to the calling method to handle (for moreinformation on the try/catch mechanism, see the Java exception-handling tutorial at java.sun.com/docs/books/tutorial/essential/exceptions/handling.html).

In WPF, you can use the try/catch mechanism in your own code, regardless of whether it iscontained in a Linked Java Object (LJO) or Method builder. However, a few points are worth not-ing about how these exceptions can be thrown to calling methods in WPF:

• You cannot use checked exceptions in a Method builder. Checked exceptions are Javaexceptions that extend the java.lang.Exception class, and are contrasted with runtimeexceptions, which extend the java.lang.RuntimeException class. Checked exceptionsare also declared in the method header, and they document the exceptions that arethrown back to the calling class. If you want to use checked exceptions in your code(and there aren’t many people who do!), you should include your Java code in LJOsrather than Method builders.

• You can throw exceptions from a Method builder (using the throw command), and thencatch these exceptions using the Error Handler builder. The Error Handler builder auto-matically adds try/catch blocks to certain areas of your application depending on howyou configure the builder.

372 Chapter 14 Error Handling, Logging, and Debugging Portlets

Page 410: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• Exceptions can also be thrown from an LJO back to a WPF Method. That is, if youaccess an LJO from a Method and an exception is generated in that LJO, and then anattempt is made to throw the exception using the throw command, the exception ispassed back to the Method builder. If the exception is not caught by the Method builder,you can still use an Error Handler builder to catch the exception, in the same way thatyou would use it with the Method builder.

The example in this section first demonstrates how to use the try/catch block in a Methodbuilder. Later in this section, another exception is thrown to demonstrate how to catch exceptionsusing an Error Handler builder, which displays a user-friendly error page to the end user. Theexample is fairly simple: its only purpose is to divide a number (the dividend) by another number(the divisor) and display the result to the screen, but it can be used to quickly and easily demon-strate all of the techniques in this chapter. If you prefer, you can use a model from a previouschapter, however, the steps in this chapter will refer to the division example just described.

Before you proceed with this section, you need a WPF project to house the model that per-forms the division. If you have a project from a previous chapter, you can use it; otherwise, youshould create a new WPF project (for more information on creating projects see Chapter 1,“Introduction to WebSphere Portlet Factory”). The project is deployed to a local applicationserver for testing (you can use the portal server if it runs on your local machine; otherwise, it isrecommended you use the IBM WebSphere Application Server Community Edition server [WASCE] that comes with WPF). Note that there is no need to deploy this application as a portletbecause what is important in this chapter is not so much the application, but the application ofcertain techniques to the development process.

After you have a project set up, you need to add the model to perform the division, andimplement the appropriate error-handling techniques. In this section, you use the followingbuilders to provide its functionality:

• Action List (x2)

• Page (x2)

• Variable (x4)

• Method

• Text

• Error Handler

Creating a Model

Create a new model called division in your project, under the folder WEB-INF/models/chap-ter14. The model should be based on the Main and Page template, using a Page Type of SimplePage. For more information on creating models, see the example in Chapter 1.

Error Handling 373

Page 411: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

After it is created, your model should have two builders in it: an Action List called mainand a Page called page1. The Action List runs automatically whenever the model is run and opensthe page1 Page.

Modifying the Results Page

Open the Page builder, and change the contents of the Page Contents (HTML) input to the HTMLlisted in the following:

<html>

<body>

<div align=”center”>

The dividend divided by the divisor is:

<span name=”result”></span>

</div>

</body>

</html>

This page contains a single span tag called result. A Text builder is used later to display theresult of the division at this tag. Save the builder call when you are finished.

Adding Division Variables

The next step is to add variables for the dividend, divisor, and result. You can do this with threeVariable builders. Add three Variable builder calls to your model (you can add a Variable buildercall from the Builder Palette, which you open by clicking the icon in Outline view) and spec-ifying each variable as type Integer. The first builder call should be called dividend with an Ini-tial Value of 10, the second should be called divisor with an Initial Value of 5, and the thirdshould be called result (you can leave the Initial Value for the result Variable blank, as it will beoverwritten later). Save the model when you’ve added all three builder calls.

Defining the Division Process

Next, you need a method to perform the actual division. Add a Method builder call to the modeland name it division, and then change the Return Type to void as there is no need to return anyvalues from the method. Change the Method Body so that it displays as shown in the following:

{

try

{

//divide dividend by divisor, and store result in ‘result’

�variable

webAppAccess.getVariables().setInt(“result”,

webAppAccess.getVariables().getInt(“dividend”) /

�webAppAccess.getVariables().getInt(“divisor”));

374 Chapter 14 Error Handling, Logging, and Debugging Portlets

Page 412: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

}

catch (java.lang.ArithmeticException e) {

}

}

Note that the division itself is enclosed in a try block. The JVM attempts to divide the divi-dend Variable by the divisor Variable, and place the result in the result Variable. If an Arith-meticException is raised (as happens, for example, when the divisor is zero), the exception iscaught by the catch block. The catch block doesn’t do any further processing, but it prevents anonuser-friendly error message from displaying to the screen. Later in this chapter, you modifythe catch block to throw an additional exception, which you then catch using the Error Handlerbuilder. Save the builder call when you’ve finished editing it.

To run the division Method, open the main Action List and insert an action before the page1action to run the division Method. You can do this by right-clicking on the page1 action andselecting Insert to insert an action, and then selecting Methods\division for the first action usingthe Select Action dialog (which you can open by clicking the ellipsis icon next to the first action).Save the builder call when you are finished.

Displaying the Result

Add a Text builder call to the model called displayResult. This builder call places the value ofthe result Variable onto the page1 page. Set the Page input to page1 and the Tag input to result toconfigure the correct location for the result, and then select the result variable for the Text input (itdisplays in the input as ${Variables/result}). Save the builder when you are finished.

Running a Preliminary Test

Run a quick test of the division model from the WPF Designer, which you can do by clicking the icon on the toolbar. This runs the currently active model (for instance, division) with the last

run configuration you used. If you have not set up a run configuration before, you are prompted todo so—create a new configuration under the WebSphere Portlet Factory Model category (if youwant more information on setting up a run configuration, see the “Testing the Application” sec-tion in Chapter 1).

Your default Web browser should open, and the following message should be displayed:

The dividend divided by the divisor is: 2

This result is expected, as 10 divided by 5 is 2. Now change the Initial Value input for thedivisor to 0 so that the division Method attempts to divide 10 by 0. Run the model again, and youshould see the following message displayed in the browser:

The dividend divided by the divisor is:

Because the result of dividing any number by zero is undefined, an ArithmeticExceptionwas raised when you tried to run the division Method. This exception was then caught by the

Error Handling 375

Page 413: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

catch block in your code, so as far as the JVM is concerned, the ArithmeticException was han-dled (however, no result was assigned to the result Variable). Notice that if you comment out thetry and catch blocks in the division method so that only the lines that perform the actual divisionremain (as well as the curly braces that surround the entire method), the exception is not handledand the error shown in Figure 14.1 is displayed to the screen. You can click the ‘Click here for adetailed error message’ link on this screen to see the exception message and the full stack trace.

376 Chapter 14 Error Handling, Logging, and Debugging Portlets

Figure 14.1 An unhandled exception displayed on the screen.

Creating a Custom Exception

To demonstrate the use of a custom exception and show how to catch an exception using the ErrorHandler builder, you need to create a custom Java exception to throw from the division Method.You don’t need to throw custom exceptions to use the Error Handler builder (you can use anytype of exception), but custom exceptions are useful in that they enable you to cater to an excep-tion that is thrown only when you explicitly throw it, which enables you to describe and definethe nature of the exception itself.

In this example, you create a custom exception called MyException, which is a catch-allexception for WPF processes that can’t be handled. A MyException is thrown only when youexplicitly call the ‘throw new MyException();’ command in a Java Method.

Create a Java source file for the MyException class by selecting File, New, Class in theWPF Designer. Specify com.ibm as the package (substituting your own company name for ibm)and MyException as the name (note that the package com.ibm is used throughout this chapter,but in each case, you should substitute your own company name for ibm). Also, change theSuperclass of the class to java.lang.RuntimeException. Press Finish to create the customexception class.

After the class is created, it will automatically open in the WPF Designer. Edit the file sothat it contains a constructor method, as shown in the following:

package com.ibm;

public class MyException extends java.lang.RuntimeException

{

public MyException(java.lang.Exception e)

{

}

}

Page 414: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The constructor MyException executes whenever the MyException is thrown, and receivesan Exception object as an argument. In the “Debugging” section of this chapter, you add somecode to the constructor to display a debugging message whenever the MyException is thrown.

Save the file when you are finished.

TIP

Depending on how you have configured the WPF Designer, you may get a warning whenthe MyException class is open. This indicates that you haven’t declared a serialVersionUIDfield. In the current example, this warning can be disregarded. For more information on thiswarning, see the example in Chapter 8, “Using Java in Portlets.”

Throwing the Custom Exception

To throw the MyException, edit the catch block in your division Method so that it displays asfollows:

catch (java.lang.ArithmeticException e){

//throw MyException back to Error Handler builder

throw new MyException(e);

}

This throws a MyException, passing the ArithmeticException e as an argument. The argu-ment is passed so that information on the ArithmeticException is accessible in the MyExceptionclass, which will enable you to process the exception further if desired. Before you save themethod, you also need to expand the Import List section of the builder call, and modify the InputList input so that it contains an entry for com.ibm.MyException (substituting your own companyname for ibm). If you do not take this step, the MyException class is not recognized. Alterna-tively, you can specify the full package name when you throw the MyException, but this canmake your code more difficult to read. Save the method when you are finished.

If you test your application now, an ArithmeticException is raised in the try block (becauseyou are trying to divide by zero), which is then caught and a MyException is thrown. Becauseyou aren’t handling the MyException, a fairly nonuser-friendly message is displayed on thescreen, so the next step is to display a different error page.

Adding an Error Page

To add a more user-friendly message whenever the MyException occurs, add a Page builder callto the model and name it errorPage. Change the Page Contents (HTML) input so that it reads asfollows:

Error Handling 377

Page 415: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

<html>

<body>

<div align=”center”>

<div style=”font:12pt Arial;font-weight: bold;color:

#336699;”>Error Page</div>

<br>

An error occurred while loading this page. Please

�contact your system administrator.

</div>

</body>

</html>

Save the builder call when you are finished.

Adding an Error Flag

The next step is to add a variable that flags whether the MyException has occurred. This is usefulbecause you can then add an if-then statement to the main Action List, which checks the value ofthe flag, and displays only the page1 page when no MyException has occurred. If you don’t dothis, page1 is displayed regardless of whether there is an exception (in the event that there is noexception, page1 executes as per normal; in the event that there is an exception, the JVM consid-ers it handled by the catch block created by your error handler, and passes control back to themain Action List to display page1).

Add a Variable builder call to the model, and name it MyExceptionFlag. Change the Typeof the Variable to Integer, and then set the Initial Value to 0, and save the builder call. After youhave done this, open the main Action List and encapsulate the page1 action in an if-then block,which results in the page1 action only being run when the value of MyExceptionFlag is 0. To dothis, insert an action above page1 and open the Select Action dialog for the new action by press-ing the ellipsis icon to the far right of the new row. From the Select Action dialog, select ‘if’ fromunder the Special, Conditional category and press OK. You will see a dialog asking you to enterdetails for the if statement—specify the details as shown in Figure 14.2, and then press OK. Thestatement should then display in the Actions input as ‘!IF (${Variables/MyExceptionFlag} == 0)THEN’.

To close the if block, add another action at the end of the Actions list, selecting endif fromunder the Special, Conditional category, and then press OK. The action displays in the Actionsinput as !ENDIF. Save the builder call after you have added both of these actions.

378 Chapter 14 Error Handling, Logging, and Debugging Portlets

Page 416: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Error Handling 379

Figure 14.2 Configuring the if-then statement.

Adding an Error Action

The next change to make is to define the sequence of actions to execute when the MyException iscaught. The sequence of actions is to first assign a value of 1 to the MyExceptionFlag (to indicatethat an exception has occurred and to prevent page1 from displaying), and then to display theerrorPage you created earlier. To do this, add an Action List builder call and name it catchMyEx-ception. For the first action in the Actions input, select Assignment from under the Special cat-egory in the Select Action dialog, and then specify the MyException variable as the Target (itdisplays as Variables/MyExceptionFlag) and specify 1 as the source. Press OK to add the action,which should display in the Actions list as ‘Assignment!Variables/MyExceptionFlag=1’. For thesecond action, select the name of the error page (errorPage) and save the builder call.

Adding an Error Handler

The final step in the error-handling process is to tie everything together; try to run the divisionMethod, catch the MyException if it occurs, and then run the catchMyException Action Listwhen the exception is caught.

To do this, add an Error Handler builder call and configure it as shown in Figure 14.3. An important point to be aware of with this builder is that it is possible to use it to either

catch exceptions thrown by a specific action (as you have done with the division Method in theexample) or catch all exceptions thrown by a model. You can toggle this setting by changing thevalue of the Exceptions input. If you want to have a generic error page displaying whenever anexception is thrown and not recovered from, then you might opt for catching all unhandled excep-tions (however, when doing this, be aware of the exceptions that you’re catching, and make sureyou are handling them appropriately).

Save the builder call when you are finished.

Page 417: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

380 Chapter 14 Error Handling, Logging, and Debugging Portlets

Figure 14.3 Configuring the Error Handler builder.

Testing the Division Model

If you test the division model now, you can see that the exception is caught and the errorPage dis-plays accordingly, as shown in Figure 14.4. If you change the value of the divisor Variable to aninteger other than zero, you will see that the original result message displays instead.

Figure 14.4 The error page.

At this point, you are throwing, catching, and handling the ArithmeticExceptions in thedivision model, but there is little in the way of feedback to help you assess exactly what yourapplication is doing when it runs. The next two sections discuss how to obtain such feedback byextending the current application using WPF debugging and logging techniques.

Debugging

There are numerous ways to debug your applications in WPF. The first and probably quickestway is to look for errors and warnings showing up in the Problems view of the WPF Designer(warnings appear with an icon next to them). Although warnings don’t necessarily preventyour application from running, they can help to explain runtime errors, and you should at least beaware of why each warning is displayed.

After you have addressed the warnings in your application, it is useful to add debuggingstatements into your code so that you can get feedback on what your application is doing as itruns. The example that follows adds a few debugging statements to the division model andexplains how to view the results.

Page 418: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

If you use Rational Application Developer or Rational Software Architect for your IDE or youuse an extended version of Eclipse with the Web Tools Project tools, there may be a set ofvalidators turned on that can generate numerous warnings. The JSP, HTML, and WSDLvalidators in those tools are meant for developers hand-coding those artifacts, and the val-idators get confused by the WPF-generated pages and Property Broker-based WSDL files.It is best to turn these validators off in WPF projects, so that you can see the actual warn-ings that pertain to your application models (you can do this by filtering the Problems viewor by configuring the WPF Designer preferences).

Debugging Statements

Open the main Action List and insert an action at the top of the Actions input, and then open theSelect Action dialog for this action. Select Special, SystemOut in the Select Action dialog. In theprompt that follows, specify debugging information such as Division application start-ing..., and then press OK. Add a similar Action at the end of the Actions input, but specify thedebug text as Application finished successfully. When you test this application in amoment, you will see how to access this debugging information.

Open the division Method, and insert the following lines immediately below the commentin the try block:

System.out.println(“Attempting to divide dividend by

�divisor”);

System.out.println(“Value of divisor: “ +

�webAppAccess.getVariables().getInt(“divisor”));

As before, this also causes particular debugging messages to be printed when your applica-tion runs. Save the builder call when you are finished.

TIP

You can print the contents of variables (including XML variables) simply by specifying themas the argument to a SystemOut or System.out function.

Before you debug the model, change the value of the divisor Variable to a nonzero integer,and save the model. Run the application from the WPF Designer, and then open the System.outfile on the application server specified in your application server deployment configuration (thisfile is normally located under the logs directory of your application server). Note that if you areusing WAS CE, the file is actually called server-log4j.properties and is found under the var/logdirectory of WAS CE (it also displays in a console window if you use one).

Debugging 381

Page 419: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Scroll to the most recent messages in the file, and you should see all of the messages speci-fied in the main Action List display in sequence. The exact format of these messages differsdepending on the application server version you use, and also on how your application server isconfigured. As an example, in a default WebSphere Portal Server 6.0 installation, the messagedisplaying the value of the divisor displays similarly to the following:

[10/03/08 21:56:29:688 EST] 00000060 SystemOut O Value of divisor: 1

TIP

If you use SystemOut or System.Out statements in your code, be sure to remove themwhen you are done with them. This improves the performance of your applications and italso helps to un-clutter your log files.

Next, open the MyException Java class and add the following line into the MyExceptionconstructor:

System.out.println(“A MyException occurred: “ + e.getMessage());

This prints a debugging message to the console whenever the exception is thrown. Themessage incorporates the error message taken from the ArithmeticException e. Save the file whenyou are finished, and then change the value of the divisor Variable to 0 so that the MyException isthrown. Save the model and run the model again.

Among your other debugging messages, you should now also see a debugging messagefrom the MyException class, similar to that shown in the following:

[8/04/08 20:31:52:922 EST] 0000004d SystemOut O A MyException

occurred: / by zero

Using Eclipse Debugging

Another common way to debug WPF applications is to use the debugging capabilities of the IDE.These capabilities enable you to step through your code (including the automatically generatedWPF code) one line at a time.

To set this up, you need to configure debugging on both the application server and in theWPF Designer.

TIP

When debugging, it is often helpful to look at the generated code for your application in theWebApp Tree tab of the Model Editor. This can tell you exactly what WPF generates as aresult of the inputs in your builders.

382 Chapter 14 Error Handling, Logging, and Debugging Portlets

Page 420: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Configuring the Server

Before you can debug your application, you need to start the debugging service on the applicationserver. The exact way that you do this differs depending on the application server and version youuse, so you should consult your server’s documentation for specific instructions. As a startingpoint, if you use a WebSphere Portal 6.0 server, you can find the setting on the Admin consoleunder the Servers, Application Servers, WebSphere_Portal, Debugging Service category (there isa checkbox called Startup that you need to enable). For WAS CE, you can specify jpda startas the first argument to the geronimo script (this process is discussed under the section Reference,Commands, Geronimo of the version 1 WAS CE user documentation).

Configuring the WPF Designer

After you enable debugging on the server, you need to configure the WPF Designer for debug-ging as well. To do this, first open the Project Properties dialog by selecting Properties from theProject menu in your IDE. Then, open the Java Build Path section and switch to the Source tab.Click the Add Folder button, and add the WebContent/WEB-INF/factory/generated folder as aSource directory for your project. This directory contains the automatically generated Java codein your application, and after you’ve added it, you can debug WPF-generated code and your owncode (stored in the WebContent/work/source directory). Accept your changes and close theProject Properties dialog.

Next, you need to create a Debug configuration. To do this, open the Debug Configurationdialog by clicking Run, Debug. The dialog shown in Figure 14.5 should display.

After the dialog is open, select Remote Java Application from the tree list and press theNew button to create a new configuration. Give the configuration a name (such as WPF debugconfiguration). Some settings will display in the right pane; confirm that these settings arecorrect (in particular, check that the hostname and port are correct).

Switch to the Source tab of the dialog, and press the Add button to add a source lookuppath. Click Workspace Folder, and then select the generated source folder in your project (Web-Content/WEB-INF/factory/generated) and press OK. The generated folder should display in thedialog as shown in Figure 14.6.

Press Close to save the configuration when you are finished.

TIP

Temporarily disabling builders in a model can help you isolate problems in your application.

Debugging 383

Page 421: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

384 Chapter 14 Error Handling, Logging, and Debugging Portlets

Figure 14.5 The Debug Configuration dialog.

Figure 14.6 Adding the generated folder to the debug configuration.

Debugging YourModel

To debug your model, switch to the Debugging perspective in the WPF Designer (which you doby selecting Window, Open Perspective, Debugging), and then click the icon to run the lastdebug configuration you used (you can choose the debug configuration you want by selectingRun from the Debug menu). Your model runs in debug mode, which means that you can step

Page 422: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Logging 385

through it as you would any other Java application (this includes setting breakpoints in the gener-ated code).

The next section of this chapter discusses some additional debugging techniques that usethe logging capabilities of WPF.

Logging

Another way to debug your WPF applications is to log points of interest in them while they run.In WPF, this is achieved with log4j logging, which is a commonly used Java logging framework.

Before you proceed with the example in this section, there are a few points that you shouldunderstand about how logging works in WPF. The first thing you need to know is the location ofthe logs themselves. WPF log files are stored under the WEB-INF/logs directory in yourdeployed applications (don’t use the WebContent/WEB-INF/logs directory in the WPF Designerbecause the log files there are not necessarily updated when you run the application). Differentlog files are used to log different aspects of your application, and several of these files are intro-duced in the example later in this section.

The other important point is that you can configure your logging settings in the WebCon-tent/WEB-INF/config/log4j.properties file. This file contains settings for how, where, and whenWPF logs information. It also contains a set of logging properties that you can change to deter-mine what WPF is actually logging. Each of these logging properties can be configured to log dif-ferent levels of information. The default logging levels used in WPF are as follows:

1. DEBUG

2. INFO

3. WARN

4. ERROR

5. FATAL

The lowest of these levels (DEBUG) provides the most amount of debugging information,and subsequent levels provide progressively less information until the highest level (FATAL),which logs messages only when an error occurs that can’t be recovered from. These levels pre-vent you from cluttering up your logs unnecessarily, and in some cases, higher levels can alsohelp to improve system performance. Later in this chapter, you will see how to use these levels tolog the division model. For information on some of the more useful logging properties in WPF,see Appendix B “Portlet Factory Properties.”

Debug Tracing

The first logging technique you use for the division model is debug tracing, which you can addvia the Debug Tracing builder. The Debug Tracing builder enables you to trace actions in yourapplication, and log various types of information about those actions, such as variable values andHTTP request parameters. By default, this information is written to the debugTacing.txt log filein your application’s logs directory.

Page 423: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

Before you use the Debug Tracing builder, set the level in the bowstreet.system.debugTrac-ing property to DEBUG. When this property is set to DEBUG, it provides more information,such as session ID and profile statistics. To improve performance, set the property to ahigher level after you have finished debugging.

Add a Debug Tracing builder call to the division model and name it traceException-Flag. You use this builder to log the value of the MyExceptionFlag Variable. Enable the ‘Traceall actions’ checkbox so that all actions in your model are logged. To define the specific cate-gories that you want to trace, you need to edit the log4j.properties file, but before you do this,change the value of the ‘Additional debug input’ input to the MyExceptionFlag Variable, so thatyou can track the value of this variable as it changes (after you’ve selected it, it displays in theinput as ${Variables/MyExceptionFlag}). Notice that there is an input on the Debug Tracingbuilder to Log parameters, which logs HTTP request parameters for your application. This set-ting is useful if you want to see the fields that are sent when forms are submitted. Leave this boxunchecked, as you are not submitting anything in the current example, and save the builder callwhen you are finished.

Run the division model from your IDE, and after it has run, open the debugTracing.txt filein the logs directory of your deployed application (on the server specified in your applicationserver deployment configuration). You should see output similar to the following:

*-- TIME: [2008-04-10 10:46:24,438] --*

Category: bowstreet.system.debugTracing

Priority: INFO

Thread: WebContainer : 0

Msg: Debug Tracing

Session: uoiZFaqhpsH29-i1dysbsSY

Model: chapter14/division

Stack Trace:

234 672 Method: main

${Variables/WPFExceptionFlag} = 0

47 47 .Method: division

${Variables/WPFExceptionFlag} = 0

203 203 .Page: page1

${Variables/WPFExceptionFlag} = 0

From this output, you can see the sequence of actions in your model as they run and howlong each action takes in milliseconds (the first column is the amount of time spent in each action,and the second column is the amount of time in that action and all subactions called by thataction). In the previous example, the main action took less than 672 milliseconds in total to run(but only 234 miliseconds were spent inside the main action), and the division method took less

386 Chapter 14 Error Handling, Logging, and Debugging Portlets

Page 424: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

than 47 milliseconds. Notice also that the value of the MyExceptionFlag is logged as each actionis executed.

Next, open the log4j.properties file in the WPF Designer. The logging properties in this filehave a particular level assigned (in most cases, this is WARN, by default, which means that virtu-ally no debugging information will be logged) and an appender that defines additional outputlocations (such as the console). Most properties have a default appender with a similar name tothe property itself, which defines default settings for that property. See Appendix B for a list ofsome of the more useful properties in the log4j.properties file.

Change the log4j.logger.bowstreet.system.modelActions property to DEBUG,ModelAc-tions. This property notifies you of the actions that are running in your model and how longeach action takes to execute. Save the log4j.properties file when you are finished.

Run the model again, and then reopen the debugTracing.txt file. At the end of the file, youshould see output similar to the following:

*-- TIME: [2008-04-10 10:47:00,156] --*

Category: bowstreet.system.debugTracing

Priority: INFO

Thread: WebContainer : 0

Msg: Debug Tracing

Session: GRrAVkOj6jztWbzkbTgBVvX

Model: chapter14/division

Stack Trace:

Start Request: WebAppRunner.doRequest

0 0 [chapter14/division]

0 47 Instantiate: chapter14/division

31 31 .Regen: No profile

16 16 .Compile: Methods Class

0 0 Method: main

${Variables/MyExceptionFlag} = 0

0 0 .Method: division

${Variables/MyExceptionFlag} = 0

Several new actions have now been added to the log, including actions to regenerate yourmodel and compile your code. Note that the value of the MyExceptionFlag is not logged until themain method executes. This is because it doesn’t exist before then and there are some actions thathave zeroes next to them (these actions took less than 1 millisecond to run). Additionally, notethat if you look in the logs directory of your deployed application, the logging messages formodel actions are written to the modelActions.txt file.

Spend some time experimenting with some of the different log4j properties, checking thelogs directory as you go. For a list of some of the more useful properties, see Appendix B. Notethat before you start experimenting with properties files, it is a good idea to back them up first, sothat it is easier to revert to the original versions later if required (although you can always copythe properties files you need from a new WPF project).

Logging 387

Page 425: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Using a Custom Logging Category

Custom logging categories can be used to log events that don’t properly fit under any of the otherlog4j logging categories. For example, to log MyExceptions in the division model, add a LoggingCategory builder call to the model and name it MyExceptionLogger. Specify the Log4j Cate-gory name as bowstreet.application.MyException, which defines how the message islabeled in the logs (the bowstreet.application prefix is usually employed to name loggingcategories). Change the Associated Appenders input to UserLog, as the default setting will notwrite the output to a log file. Save the builder call to complete the configuration of your customlogging category.

To use the logging category, you need to log a message against the new logging category atthe desired log4j level. Open the catchMyException Action List and then open the Select Actiondialog for a new action at the bottom of the Actions input. Select the warn method for the new cat-egory from the bottom of the Methods\MyExceptionLogger category (just above the Pages cate-gory, as shown in Figure 14.7), and then specify the message on the resulting dialog asMyException occurred. Check value for divisor. Save the builder call when you arefinished.

388 Chapter 14 Error Handling, Logging, and Debugging Portlets

Figure 14.7 Logging a new debug message.

To test the changes, make sure the divisor Variable is 0 (so that a MyException is thrown),and run the model. Open the userLog.txt log file in your logs directory, and you should see anentry similar to the following:

Page 426: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

*-- TIME: [2008-03-12 11:45:03,062] --*

Category: bowstreet.application.MyException

Priority: WARN

Thread: WebContainer : 1

Msg: MyException occurred. Check value for divisor.

Note that you can toggle custom logging messages on or off by setting the appropriatelevels for them in your log4j.properties file. For example, if you create a MyException categoryproperty in your properties file as follows, the previous logging message would not be written tothe logs because only messages with a level of ERROR or higher are logged:

log4j.logger.bowstreet.application.MyException=ERROR,UserLog

Note that you need to add the prefix ‘log4j.logger’ before the property name. Also, beaware that the appender specified in the log4j.properties file overrides any appender specified inyour Logging Category builder call.

TIP

Whenever you upgrade a WPF project, you are prompted about whether you want to over-write the log4j.properties file with the default properties file. If you have made changes toyour properties file that you want to keep, you should back up these properties and selectYes when you receive the upgrade prompt (so that you receive WPF product updates).Youcan add your changes back in after WPF has finished the update.

Server Stats

Server stats give you various metrics about your application, which you can configure via thelog4j.properties file. You should always leave server stats set to at least INFO because this settingreturns useful information about your application, and it does not affect performance. See Appen-dix B for a list of useful properties you can use to configure server stats.

By default, server stats are enabled and run at five-minute intervals, so after you run yourapplication, the appropriate metrics are logged to the serverStats.txt file every five minutes. Openthis file now and you should see output similar to the following (for the default level of INFO):

*-- TIME: [2008-04-10 10:57:14,734] --*

Category: bowstreet.system.server.logging.serverStats.default

Priority: INFO

Thread: ServerStatsThread

Msg: Sessions: 1

RestoredSessions: 0

ModelCacheRegenEntries: 1

Logging 389

Page 427: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Regens: 2

RegensFromCache: 0

OutputCacheHits: 0

OutputCacheMisses: 0

MemTotal: 806156800

MemFree: 58141824

MemInUse: 748014976

ErrorsLogged: 0

SevereErrorsLogged: 0

WarningsLogged: 0

PeakSessions: 1

ParallelModelRequests: 0

WebAppRequests: 2 Latency: 3211

WebAppRequests/chapter14/division: 2 Latency: 3211

WebAppRequests/chapter14/division/main: 2 Latency: 3211

WebAppSOAPRequests: 0

WebAppMethodClassWritten: 1

WebAppJSPSourceWritten: 0

WebAppsInstantiated: 2

Profile cache hits: 0

Profile cache misses: 0

Profile Set cache hits: 0

Profile Set cache misses: 0

ProfileSet cache hits: 0

ProfileSet cache misses: 0

Notice that this log enables you to monitor how effectively your application is utilizing sys-tem resources, and it includes various metrics for monitoring memory use and cache hits/misses.The bold section shown in the output shows the number of WebApp requests in the last logperiod. Notice that there is one point in the application where some latency has been recorded:3,211 milliseconds in the division Method. These statistics can help you pinpoint problem areasand determine which methods take longer than they should. In this case, the latency is low andmay have been caused by a temporary spike in activity on the server; it is likely that the next timethe model is run, there will be no latency at all.

TIP

Some builders (such as the SQL Call builder) have built-in logging capabilities. To find outwhich builders in your model have these capabilities (and to toggle them on or off), use theOutline view in the WPF Designer. From the Outline view, press the Icon, and thenselect Debug Inputs. The resulting popup window lists all of the builders in your model thatuse built-in logging and enables you to turn them on or off.

390 Chapter 14 Error Handling, Logging, and Debugging Portlets

Page 428: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Summary

In this chapter, you learned how to use the error handling, debugging, and logging capabilities ofWPF to improve the quality of your WPF applications. You learned about the use of the ErrorHandler, Debug Tracing, and Logging Category builders, and you built a sample applicationusing these builders. You also learned about the use of log4j in WPF.

Chapter 15, “Performance and Process Optimization,” discusses the different ways inwhich you can optimize the speed and architecture of your applications, and it includes a sectionon creating your own builders.

You can find more information about the techniques discussed in this chapter in the WPFproduct help, as well as in the WPF Best Practices Wiki page on the Web.

Important Points

• Error handling can be implemented in WPF with the use of try/catch blocks. This can bedone either in Java or in the Error Handler builder.

• You can debug Java code using System.Out statements. Similarly, you can use theSystemOut command to debug Action Lists.

• You can step through the execution of your code line by line using the Eclipse debugger.To use this feature, you need to start the debugging service on the application server andthen configure Eclipse for debugging.

• WPF uses log4j logging to enhance its debugging capabilities. These logs are stored inthe WebContent/WEB-INF/logs directory of your deployed application, and they areconfigured in the log4j.properties file.

• The Debug Tracing builder enables you to debug tracing in your model, which logs var-ious metrics to the debugTracing.txt file. You can configure various categories for debugtracing in the log4j.properties file.

• The Logging Category builder enables you to define custom logging categories, whichare useful for when you want to log messages that don’t easily come under any of theexisting logging categories.

• Server stats give you useful metrics on your application’s performance. The INFO set-ting for server stats enables you to log useful performance information without affectingsystem performance.

Important Points 391

Page 429: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 430: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

393

C H A P T E R 1 5

Performance andProcess Optimization

This chapter outlines some of the ways in which you can improve the speed, efficiency, and archi-tecture of your portlet applications. A number of techniques are discussed: caching, data set size,builder calls, session size, profiling, Ajax, and Dojo. Also, an example at the end of the chapterdemonstrates how to optimize the portlet development process by creating your own builder andnew model wizard. By the end of the chapter, you will be aware of a family of techniques thatshould help you improve your portlets in a variety of different environments and conditions.

Each of the files in this chapter is available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 15 folder (instructions for copying these files into yourproject are included in a readme.txt file in the same folder); however, to increase your under-standing of the topics discussed, it is recommended that you create these files yourself by follow-ing the example in this chapter.

The following topics are covered in this chapter:

• Performance

• Custom builders

• Creating a new model wizard

Performance

This section discusses some common ways to improve performance in your WebSphere PortletFactory (WPF) applications. Many of these suggestions do not apply in every scenario, so if youhave a particular WPF application in mind—or a particular development scenario—feel free toskip to the sections more relevant to your requirements.

Page 431: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Caching

You can cache the output of specific actions in WPF by using the Cache Control builder. Thisbuilder is useful in scenarios where you have many users performing the same actions that pro-duce the same results. Where the results are different for each user, you need to rerun the actioneach time.

If the results change over time but are the same for every user, then you should still con-sider using a Cache Control builder. In this scenario, you need to set the builder’s ‘Refresh Inter-val (secs)’ input so that the results from the builder are suitably up to date (this will, of course, bedifferent in every scenario). In some scenarios, even a slight inaccuracy in the method’s output isunacceptable, so in these cases you should not use the Cache Control builder.

Several of the other WPF builders also have built-in caching features. For example, the Ser-vice Operation builder has a section called Result Caching that caches the results of the operation(this actually does the same thing as a Cache Control builder that points to the service operationcall). Similarly, the Lookup Table builder has a ‘Refresh interval (secs)’ input that lets you con-figure when the contents of the Lookup Table should be updated. There is no difference in thecaching used between these builders; however, in some cases, you may find it more convenient touse the built-in caching of certain builders instead of a Cache Control builder (for example, if youalready have a Service Operation builder, you can cache its results directly from the builder callwithout having to add a Cache Control builder). Having said this, if you are making extensive useof caching, you might want to use Cache Control builders so that you can easily see where all ofyour model’s caching settings are.

TIP

The log4j.logger.bowstreet.system.server.logging.serverStats property is particularly goodfor analyzing the use of caching in your application. By default, the output of this property iswritten to the serverStats.txt file in the logs directory of your deployed application every fiveminutes. This output also provides various types of information about the performance ofyour application, such as performance by model action. For more information on serverstats, see Chapter 14, “Error Handling, Logging, and Debugging.”

A caveat worth noting is that cached data is profile-specific, which means that every differ-ent profile-model combination has its own cache. This probably won’t be a problem in most sce-narios, but you should at least be aware that as the number of different profile-modelcombinations in your application increases, so do the corresponding memory requirements.Because of this, you should try to cache non-profiled models instead of profiled models whereverpossible (although the degree to which you can do this depends on the requirements of yourapplication).

394 Chapter 15 Performance and Process Optimization

Page 432: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Data Set Size

Retrieving large data sets can be slow and memory-intensive, particularly if the data isn’t cachedand you have a lot of concurrent requests. Of course, if the performance of data retrieval is anissue, you can (and should) use the Cache Control builder on your data retrieval methods, butthere are some other steps you can take to make your data source calls smarter. For example, youcan increase the performance of data retrieval operations by reducing the size of the data setsreturned (such as by only returning customers relevant to the current user, rather than returning anentire database of customers). In other words, any queries to your data should be as restrictive aspossible, and you should design your interfaces in such a way that users don’t have to sift throughunwanted data.

After you have done this, if you are still returning large data sets that have an impact on sys-tem performance, you should look at paging your data (pagination is covered in Chapter 5, “Cus-tomizing Portlet Appearance”). With pagination, you can opt to fetch your data in small chunksrather than all at once, which can greatly speed up your applications. For example, the SQL State-ment builder has a Fetch Size input for this purpose, and the Domino Data Access builder has aFetch Subsets of Data input for partial retrieval of Domino data. Alternatively, you can also writea custom data retriever in Java by extending the com.bowstreet.builders.webapp.methods.Cus-tomDataRetriever class (an example using this approach is available on the Portlet Factory wikipage).

Builder Calls

As a general rule, the more builders in your model, the more strain you put on system resources,and large models (containing 50 builders or more) can definitely slow down your applicationsand make them harder to maintain. To prevent this from happening, try to separate your buildercalls into different models wherever possible, and use backend processes to replace builder func-tionality where appropriate. For example, it is better to run a backend Java method or Dominoagent to finalize changes to a new record rather than run a WPF Method directly from the frontend (which the user has to wait for). Keep in mind, also, that whenever WebApps regenerate inyour project the builders need to run their generation routines, and the more of these that youhave, the more of an effect it will have on performance.

If you have problems with the execution or regeneration times of your models, you can useWPF’s debug tracing features to pinpoint problem areas. To do this, set the log4j.logger.bow-street.system.modelActions property in the log4j.properties file to DEBUG level, and when yourun the application, look at the corresponding metrics in the debugTracing.txt file (for more infor-mation on logging, see Chapter 14).

Session Size

User session size can be a contributor to poor performance, but there are a number of things youcan do to prevent session sizes from spiraling out of control. The first is to reduce the use of vari-ables that store large values that differ for each user. If your variables actually refer to constants,

Performance 395

Page 433: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

for example, you can mark your variables as ‘Shared (read-only)’, which prevents every userfrom having their own copy of the variable (of course, this is not always desirable).

Also, consider marking variables as request scoped rather than session scoped, which pre-vents the variable from being stored in the session. This is useful when your variable data is notneeded across more than request; however, if the data is the same across all users, you should usethe ‘Shared (read-only)’ option instead. The effect of this is most noticeable when working withXML variables. Note that you should not use request scope for XML variables that are used inmultiple requests if the XML is hard coded into the builder, as this can result in the creation ofseparate copies of the XML data, and these copies are initialized every time the variable is used.If the XML is not hard coded into the builder, it is useful to use request scope if the data is to beretrieved dynamically and discarded after each request.

When designing WPF applications to reduce session size, you should also consider profil-ing. If you set user variables based on profiles, then you can share variables with all users in agiven profile, rather than as session variables that differ for each user. For example, if admin usersalways have a particular set of parameters on a certain screen in your UI, you can set those param-eters in variables marked as ‘Shared (read-only)’ with a value assigned by an admin profile. Thisstill allows different users to have different settings, but the settings are based on profiles andshared across all users within each profile (for more information on profiling, read the “Profiling”section later in this chapter).

Session Tracing

If you are concerned about session size in your application, you can enable session tracing to findout how big your sessions actually are. To do this, open the bowstreet.properties file and changethe bowstreet.diagnostic.trace.enabled property to true. Then uncomment and set the bow-street.diagnostic.trace.sessionSize.interval to 1. This causes session information to be logged tothe sessionsize.csv file in the logs directory of your deployed application every second, so everyrequest will log session information (provided that at least one of the session variables changes).You can leave the bowstreet.diagnostic.trace.sessionSize.userName property blank. Restart theapplication server and then run your application to kick off the trace, recreating any potentiallyhigh-load scenarios that you would like to test.

A few caveats about session tracing should be noted:

• Running session tracing for long periods of time can affect performance (particularly ifyour sessionSize.interval is set to log information every second), so you should disablesession tracing after you have gathered the desired information. To disable session trac-ing, set the bowstreet.diagnostic.trace.enabled property in the bowstreet.properties fileto false, and then restart the application server.

• To ensure accurate metrics when running session tracing, it is important that only asingle user accesses the traced application while the trace occurs.

396 Chapter 15 Performance and Process Optimization

Page 434: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

After you have run your session tracing, check the contents of the sessionsize.csv file. Theoutput is split into several columns, which are described in Table 15.1.

Table 15.1 Columns Used in the sessionsize.csv File

ColumnName Column Description

Model Model in which object occurs

Name Name of object

Type Data type of object (for example, java.lang.Integer)

Scope Scope of object

Size In memory size of object

StringSize Size (in characters) of object when represented as a string

The Size metric is computed by counting the actual size of the object in memory, whereasthe StringSize metric is computed by counting the number of characters returned by the toStringmethod. Although these sizes are similar in many cases, there may be discrepancies for certaintypes of variables. In particular, in memory XML data is often much larger than the XML stringsreturned from the toString method (XML variables take up more space than String variables, soyou shouldn’t use XML for simple single value strings).

The Scope metric provides a code that corresponds to a particular variable scope. The pos-sible variable scopes are included in Table 15.2. Note that only variables with a scope of 0 or 1 arestored in the user session, so these are the only variables you need to be concerned about whenanalyzing session size.

Table 15.2 Variable Scopes Listed in the sessionsize.csv File

Scope Code Scope Description

0 Persisted for failover

1 In session, but not persisted for failover

2 Shared, read-only

3 Request scoped

Performance 397

Page 435: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

TIP

When caching a variable using the Cache Control builder or the built-in caching of a WPFbuilder, note that if you store the cached results in a variable, then the reference to the Javaobject is stored, not the object itself—so even though the variable will show up in traces assession scoped, the actual data will not be duplicated for each session (each session willhold a reference to the same shared Java object).

Profiling

The “Caching” section of this chapter has already outlined some potential performance issueswith regard to using caching inside profiled models, but when using profiling in your WPF appli-cations, you should also keep in mind how the profiling mechanism works behind the scenes—itcreates separate WebApps depending on the values in your profiles. Because some WebApps canbe quite memory-intensive, a large number of profiles can put strain on system resources, so youshould try to keep the number of profiles to a minimum. In particular, you should avoid creatingseparate WebApps for every different user setting, which you might inadvertently do if you havean Edit mode in your portlet and you have allowed users to edit their own profiles (you can add anEdit mode to your portlet from the Portlet Adapter builder). If you are allowing users to edit theirprofiles, you should set the Execution Time field on your Profile Entries to true, which differenti-ates runtime values from values that require a separate WebApp. For more information on profil-ing in general, see Chapter 1, “Introduction to WebSphere Portlet Factory,” and for an exampleusing profiling, see Chapter 12, “Profiling Portlets.”

Using Ajax and Dojo

Adding Ajax and Dojo to your portlets can improve performance and increase the usability andinteractivity of your applications. For example, partially refreshing a page saves the entire portalpage from reloading, when all you might want to do is kick off a server process or update a list onthe screen. The main reason Ajax controls are used, however, is to increase interactivity, whichthey do by dynamically reacting to certain events (for example, a user clicking a button to open aDojo dialog without reloading the page), which might otherwise be difficult or clumsy to imple-ment without Ajax.

Keep in mind, however, that in some cases Ajax controls can actually decrease performance.For example, if you add Dojo dialog boxes to a form, which in turn, open large and complex formsthat take a while to load, you may find that the time taken to initially load the page noticeablyincreases. If you have several different dialog boxes on a single page, then you might find that theperformance hit increases to an unacceptable level, and you may have to look at providing thesame functionality by other means (for example, by using page tabs). When using Ajax and Dojo,then, it is a good idea to performance test your applications under the slowest conditions in whichthey will be used and determine whether the applications are still usable at that speed.

398 Chapter 15 Performance and Process Optimization

Page 436: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Custom Builders

Custom builders enable you to extend the core WPF builder set with builders that are more suitedto the unique demands of your development environment. Custom builders can be used to do any-thing from add a UI control to a page, to add entire models or Java classes to your WPF projects.If you find yourself using the same set of builders over and over again, you may decide to collatethese builders into a single, high-level builder that will automate the process of adding that set ofbuilders (custom builders can be used to call and create other builders). You may also decide tocreate builders to introduce new functionality, such as a builder to automatically implement asecurity mechanism used in your organization.

Custom builders benefit the development process in a number of ways:

• They help to automate the development process. Of course, it is likely that you will notbe able to automate every aspect of the development process, but there is certainly roomfor a custom builder whenever you are faced with tasks that need to be performed morethan once.

• They enable you to enforce architectural standards across a development team. Forexample, a custom builder can be used to create Java class skeletons or add UI controlsin a particular way.

• Custom builders have a wizard-based interface so they are easy to use, which reducesthe skill level required to use them. This is the case when custom builders are used towrite Java code.

• Although there is an initial time commitment required to create a custom builder, afterthe builder is created, it is generally faster to use the custom builder than the methodsthat the custom builder replaces. As a result, custom builders can save developers a sig-nificant amount of time.

• Development with custom builders is less error prone than traditional developmentmethods, as the process is mostly automated (of course, this also depends on the qualityand power of the builder).

• Custom builders encourage reusability.

The rest of this chapter walks you through the process of creating a custom builder and acustom new model wizard. Both of these are used to create an information portlet, which displaysinformation for a portal belonging to a fictional company. The builder automatically adds a link toan HTML page, which opens a terms and conditions page. The terms and conditions page con-tains some default text, but developers are also able to configure this text from the builder. Thepage also contains a Back button to navigate back to the original page. After the portlet is com-plete, a new model wizard is created so that the information portlet is added as one of the possibleoptions when users create a new model, showing you just how easy it is to automatically addlarge amounts of functionality with a new model wizard. A screenshot of the custom builder isshown later in this chapter in Figure 15.2, and a screenshot of the new model wizard is shown inFigure 15.6. The finished portlet is shown in Figure 15.5.

Custom Builders 399

Page 437: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Before you proceed with this section, you need a WPF project to house the model for theinformation portlet. If you have a project from a previous chapter, you can use it; otherwise, youshould create a new WPF project (for more information on creating projects, see Chapter 1). Theproject will be published as a WAR file and deployed to a portal server, and you should alsodeploy the application to a local application server for testing (you can use the portal server if itruns on your local machine; otherwise, it is recommended that you use the IBM WebSphereApplication Server Community Edition server [WAS CE] that comes with WPF).

After you have a project set up, you need to add the information model. This model uses thefollowing builders to provide its functionality:

• Action List

• Page

• Portlet Adapter

• Terms & Conditions

The Terms & Conditions builder doesn’t exist yet, but you will create it as you progressthrough this section.

Creating a Model

Create a new model called information in your project, under the folder WEB-INF/models/chapter15. The model should be based on the Main and Page template, using a Page Type ofSimple Page. For more information on creating models, see the example in Chapter 1. After it iscreated, your model should have two builders in it: an Action List called main and a Page calledpage1. The Action List runs automatically whenever the model is run and opens the page1 Page.

Modifying the Page

Open the Page builder, and change the contents of the Page Contents (HTML) input to the HTMLlisted here:

<html>

<body>

<div align=”center”>

<div style=”font:12pt Arial;font-weight: bold;color:

#336699”>Welcome!</div>

<br>

Welcome to the Acme portal. Use this portal to manage

your account, get the latest information on our

products, or browse our online store.

<br>

<br>

<span name=”terms”></span>

400 Chapter 15 Performance and Process Optimization

Page 438: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

</div>

</body>

</html>

This page displays a simple information message to the screen. The terms span tag isreplaced with a link created by the Terms & Conditions builder. Save the builder call when youare finished.

Adding a Portlet Adapter

Add a Portlet Adapter builder call to the model by selecting Portlet Adapter from the BuilderPalette (you can open the Builder Palette by clicking the icon in Outline view) and pressingOK. This will surface the information model as a portlet on the portal server specified in yourdeployment configuration. Change the name of the Portlet Adapter to information, and thenchange the Portlet Title to Information. Also, change the Portlet Description to This port-let displays information on the portal. This builder surfaces your model to the por-tal server as a portlet called Information. Save the builder call when you are finished.

Creating a Terms & Conditions Builder

The next step is to create the Terms & Conditions builder. Builders are actually comprised ofXML definition files and Java code on the backend, but you don’t need to create these artifactsmanually—in fact, you can use another builder (the Builder Skeleton) to do the work for you!Before you do this, you should create a new model to house the Builder Skeleton. You may wantto recreate or reconfigure the builder later, and it is clearer if you do this from a dedicated buildercreation model rather than from inside the information model.

TIP

Builder definition files have a .bdef extension, and are stored in the WebContent/WEB-INF/builders directory. Although you can manually edit these files, you can also create themautomatically using the Builder Skeleton builder.

Add a new, empty model to your project under the WEB-INF/models/chapter15 folder, andcall it builderTermsAndConditions. Next, add a Builder Skeleton builder to the model. Afteryou configure this builder call and save it, WPF creates the necessary builder definition and classfiles based on your settings (or, it updates them if they already exist).

Open the dropdown for the Builder Type input, and notice that there are four types ofbuilders you can create (these types are briefly described in Table 15.3). In this section, you createa Page Control Builder because you want to be able to place content onto an HTML page. SelectPage Control Builder for the Builder Type input, and notice that some of the other inputs in thebuilder (such as the Description) are automatically populated.

Custom Builders 401

Page 439: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table 15.3 Builder Types

Builder Type Builder Description

Basic Builder This option creates a simple, ordinary builder.

Page Control Builder Use this option for builders that insert elements onto a page, as thepage location aspects of the builder will be automated.

Model-Based Builder Use this option to create a custom builder based on profiled inputsin a model.

Model-Based Wizard Builder This option creates an entry in the new model wizard that enablesdevelopers to automatically create models with a particular con-figuration.

Specify the ID for the builder as com.ibm.builders.TermsAndConditions. This IDuniquely identifies the builder and also determines the value used for the Builder Class input,which holds the name of the Java class that provides the builder’s functionality. Now, enter aReadable Name of Terms & Conditions, which is the actual name of the builder as it appearsin the Model Editor and Outline view. For the mandatory Description input (this is different to theDescription input at the top of the builder, which explains the builder type), enter This builderadds a link which opens a terms and conditions page. This description displaysunder the builder title when developers are using the custom builder in the Model Editor.

Underneath the Builder Class input is a checkbox for generating a coordinator. A coordina-tor in WPF is a Java class that lets you dynamically update a builder’s interface. In this example,you use a coordinator to show and hide an input that accepts custom terms and conditions. Enablethe Generate Coordinator checkbox, and you should see the Coordinator Class input filled in withthe value com.ibm.builders.TermsAndConditionsCoordinator.

The next checkbox enables you to generate a helper, which is essentially a utility class thatcan be called from your custom builder class. Helpers are useful when you are dealing with com-plex functionality that you don’t want to store in the builder class itself. In this case, you don’tneed a helper, so leave the Generate Helper box unchecked.

The Category input defines the category under which your builder will display in theBuilder Palette. Select Custom Builders. Leave the Help File input blank, as you will not providea help file for the builder in this example (for future builders, you can create HTML pages basedon the existing WPF help pages, copy them into your project, and link to them from this input).Also, leave the Required Version input with the default value of 5.6.0, which is the minimum ver-sion required to use your custom builder. If your custom builder uses other builders that are avail-able only in certain versions of WPF (such as the Dojo builders, which are available only inversions of WPF later than 6.0.1), then you need to change the value of this input to the appropri-ate version.

402 Chapter 15 Performance and Process Optimization

Page 440: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The final input in the main section of the Skeleton Builder is for generating a builder API.This checkbox creates a Java class with the required get and set methods for each input in the cus-tom builder, essentially enabling you to override the way WPF stores and retrieves these values.By default, each builder gets and sets its data based on the type of input used (String, XML,Date), which, in most cases, is all you need. However, you might want to modify this mechanismif you want your builder to be callable from other custom builders. For example, in the code laterin this section, you will see how to access the builder API of the Button builder; if you generate abuilder API for your custom builder, then you can access the builder from other builders in thesame way. You can leave the checkbox disabled for the current example. Don’t save the buildercall yet, as you still have to define the builder inputs themselves.

Defining Builder Inputs for the Custom Builder

The final area of customization for the Builder Skeleton is the Builder Inputs section at the bot-tom of the builder, which is, of course, where you need to specify all your builder inputs. In theName section of the builder call, you can already see an input for PageLocation as a result ofselecting the Page Control Builder for the Builder Type earlier in this section. For this builder,you need to define several other inputs as well, so add some extra inputs as shown in Figure 15.1(make sure they are in the right order, as this order defines the order in which they appear in theinterface). You can define new inputs simply by clicking on blank rows and typing in the inputname, and you can move inputs by dragging and dropping them.

Custom Builders 403

Figure 15.1 Defining builder input names.

The first input, Name, defines the model-specific name of the builder as it appears in eachmodel. Select the Name input, and then change the Input Type to ‘Builder name (required)’,which automatically gives the input the behavior of a standard name input in WPF. Also, enablethe ‘Is Required’ box to make sure developers enter a name for the builder, and enter a Prompt ofName (this is the label that displays next to the input).

Select the Page Location input, and notice that the Input Type is set to Page location. Thissetting automatically adds the standard Page and Tag inputs for placing an element onto a page.

Page 441: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

After you have finished looking at the Page Location settings, select the BackAction input andchange the Input Type to WebApp action picker, which enables users to open the SelectAction dialog to fill in a value for the input. This input is used to specify an action to run when theuser clicks a Back button on the terms and conditions page. Type Back Action for the Prompt,and enter Action to run when returning from the terms and conditions page for the Help Text.The Help Text displays when the cursor hovers over the input label.

Now, select the OverrideMessage input. This input is a checkbox that enables developers tospecify whether they want to override the default terms and conditions text. When the checkboxis not enabled, the NewMessage input is hidden (the NewMessage input enables developers tospecify the custom text). The mechanism to handle this functionality is added into the Java classcreated by the Skeleton Builder, which you do later in this chapter.

Change the Input Type for the OverrideMessage input to Checkbox, and for the Prompt,type Override Terms and Conditions. For the Help Text, specify Toggles whether youwould like to override the default terms and conditions. Finally, select theNewMessage input and change the Input Type to Text area. Change the Prompt to New Termsand Conditions, and change the Help Text to Text to override the default termsand conditions.

Generating the Custom Builder Artifacts

When you are finished entering the custom builder settings, save the builder call. This automati-cally creates an XML definition file called TermsAndConditions.bdef in the WebContent/WEB-INF/builders/com/ibm/builders directory, it adds a Java source file for your builder(TermsAndConditions.java), and it adds a source file for your coordinator (TermsAndCondition-sCoordinator.java) in the WebContent/WEB-INF/work/source directory.

The builder definition file contains the settings from your Builder Skeleton. You don’t needto change the builder definition file, but if you want to share the builder with others, you need toprovide them with this file. You also need to provide them with the Java classes just mentioned(you don’t need to share the model with the Builder Skeleton). When sharing builders, it is a goodidea to export these files into a WebSphere Portlet Factory Archive, which other developers canthen easily import into their own projects (you can do this by right-clicking a project, and thenselecting Export, Other, WebSphere Portlet Factory Archive).

TIP

You can add a zip file containing your custom builder to a feature set by copying the zip fileinto the <wpf_install_location>\WPFDesigner\FeatureSets\<Web-App_version_number>\Packages folder. After you restart the WPF Designer, the package will be listed among theprepackaged WPF feature sets.

404 Chapter 15 Performance and Process Optimization

Page 442: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Modifying the Custom Builder’s Functionality

Open the TermsAndConditions.java file and have a look at the default code added by WPF. Thereis one method in the TermsAndConditions class called doBuilderCall, which is executed when-ever the WebApp is regenerated. If you scroll through the code, you can see that by default, thebuilder creates a Text builder and uses it to place some text at the page location specified by thePageLocation input. Notice also that several points in the code are marked in the following way:

/*##GENERATED_BEGIN*/

/*##GENERATED_BODY_END*/

Code that falls between these lines is overwritten by WPF whenever you update the BuilderSkeleton builder call, so any modifications you make should be made outside these areas.

In the current example, you need to overwrite the code that creates the Text builder, so thatthe custom builder’s functionality is as follows:

1. Defines HTML for the terms and conditions page

2. Creates a terms & conditions page

3. Places a Back button onto the terms and conditions page

4. Inserts a link at the PageLocation specified

To do this, replace the contents of the doBuilderCall method so that it appears as shown inthe following code snippet (note that you can also download this method fromibmpressbooks.com/title/9780137134465 under the Chapter 15 folder):

public void doBuilderCall(GenContext genContext, WebApp webApp, BuilderCall

�builderCall, BuilderInputs builderInputs, PageLocation pageLocation)

{

// System.out.println(“builderInputs: “ + builderInputs);

/*##GENERATED_BODY_BEGIN#InputAccessorCode#*/

// Generated code to get all the builder inputs

String name = builderInputs.getString(Constants.Name, null);

String backAction = builderInputs.getString(Constants.BackAction, null);

boolean overrideMessage = builderInputs.getBoolean(Constants.OverrideMessage,

�false);

String newMessage = builderInputs.getString(Constants.NewMessage, null);

/*##GENERATED_BODY_END*/

//Define HTML for terms and conditions page

StringBuffer html = new StringBuffer(“<html><body><div align=’center’>

�<div style=’font:12pt Arial;font-weight: bold;color: #336699;’>” +

�“Terms & Conditions</div><br>”);

if (overrideMessage)

html.append(newMessage);

Custom Builders 405

Page 443: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

else

html.append(“Here are the default terms and conditions.”);

html.append(“<br><br><span name=’backButton’></span></div></body></html>”);

//Create terms & conditions page

com.bowstreet.builders.webapp.api.Page pageBuilder = new

�com.bowstreet.builders.webapp.api.Page(builderCall, genContext);

pageBuilder.setName(“termsAndConditionsPage”);

pageBuilder.setPageData(html.toString());

pageBuilder.invokeBuilder();

//Place back button onto terms and conditions page

Button buttonBuilder = new Button(builderCall, genContext);

buttonBuilder.setActionType(“link”);

buttonBuilder.setAction(backAction);

buttonBuilder.setLabel(“Back”);

buttonBuilder.setPageLocation(“Page termsAndConditionsPage NameSearch

�backButton”);

buttonBuilder.invokeBuilder();

//Insert link at pageLocation

Link linkBuilder = new Link(builderCall, genContext);

linkBuilder.setPageLocation(pageLocation);

linkBuilder.setText(“Terms & Conditions”);

linkBuilder.setActionType(“link”);

linkBuilder.setAction(“termsAndConditionsPage”);

linkBuilder.invokeBuilder();

}

The modifications to this method have been made under the generated text at the top of theclass (which ends with ‘/*##GENERATED_BODY_END*/’), and replace the previous code toadd a Text builder to the page. The first block of code defines a StringBuffer with the HTML touse for the terms and conditions page. If the OverrideMessage input is set to true, the NewMes-sage is inserted into the HTML; otherwise, a default message is used (notice that the first letter ofeach input in the code has been converted to lowercase, so that the names are consistent with Javanaming standards). The second block uses a Page builder to create the terms and conditions pageitself, and the third block uses a Button builder to place a Back button onto the page. The finalblock uses the Link builder to place a hyperlink onto page1, which is used to open the terms andconditions page. Notice that the invokeBuilder method for each builder kicks off that builder’sdoBuilderCall method. For the javadoc on these classes, see the WebSphere Portlet Factory helpfile under the Reference, API documentation heading.

Save the class when you are done modifying it.

406 Chapter 15 Performance and Process Optimization

Page 444: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Modifying the Coordinator

The next step is to modify the coordinator so that the Terms & Conditions builder dynamicallyhides and shows the NewMessage input depending on whether the OverrideMessage input isenabled.

To do this, open the TermsAndConditionsCoordinator class. There are three main methodsin the TermsAndConditionsCoordinator class: initializeInputs, which runs when the builder callis created or opened from the Outline view; processInputChange, which runs whenever an inputvalue changes; and terminate, which runs whenever the OK or Apply buttons are pressed. Noticethat there are large blocks of commented code telling you how to manipulate the initializeInputsand processInputChange methods, which you can modify to suit your needs.

You need to make two changes to this class, and both concern setting the visibility of theNewMessage input based on the visibility of the OverrideMessage input. The first change will bemade to the initializeInputs method and will set the visibility of overrideMessage when thebuilder call is first opened. To make this change, enter the following code just after the‘/*##GENERATED_BODY_END*/’ line in the initializeInputs method:

//toggle newMessage input if overrideMessage has changed

defs.newMessage.setVisible(defs.overrideMessage.getBoolean());

For the next change, add the following code just after the first curly bracket under the defi-nition for the processInputChange method:

//toggle newMessage input if overrideMessage has changed

if (changed == defs.overrideMessage)

{

defs.newMessage.setVisible(defs.overrideMessage.getBoolean());

return true;

}

This checks to see if the OverrideMessage input has changed, and, if so, it sets the visibilityof the NewMessage input accordingly.

Save the class when you are finished editing it. You can come back and modify this class atany time, and it will update any instances of the Terms & Conditions builder the next time thebuilders are used.

Using the Terms & Conditions Builder

Now that you have finished configuring the Terms & Conditions builder, you need to put it to use.Open the information model again, and open up the Builder Palette to add a new builder. If youscroll through the ‘All’ category, you should see the Terms & Conditions builder, and it shouldalso display under the Custom Builders heading. Select the Terms & Conditions builder and pressOK. The builder should display in the Model Editor, as shown in Figure 15.2. Notice that theNewMessage input is hidden; if this is not the case, make sure you configured the coordinatorclass correctly.

Custom Builders 407

Page 445: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

408 Chapter 15 Performance and Process Optimization

Figure 15.2 The Terms & Conditions Builder.

Change the name of the builder call to termsAndConditions, and then specify the Pageand Tag as page1 and terms, respectively. For the Back Action, select page1 (notice that all ofthese inputs have the appropriate pickers available as a result of setting the Input Type input onthe Builder Skeleton). Leave the Override Terms and Conditions input disabled for now, and savethe builder call.

Testing the Information Model

To test the information model from your IDE, run your model from the WPF Designer by click-ing the icon on the toolbar. This runs the information model with the last run configurationyou used. If you have not set up a run configuration before, you are prompted to do so—create anew configuration under the WebSphere Portlet Factory Model category (if you want more infor-mation on setting up a run configuration, see the “Testing the Application” section in Chapter 1).An information page with a link to open the terms and conditions page should display, as shownin Figure 15.3.

Figure 15.3 The information page.

Click the terms and conditions page, and you should be taken to a new page, as shown inFigure 15.4. Clicking the Back button should return you to page1.

Page 446: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a NewModel Wizard 409

Figure 15.4 The default terms and conditions page.

Now open up the Terms & Conditions builder call again, and enable the box to override theterms and conditions. If you have set up the coordinator class correctly, the NewMessage inputshould now display. Enter some new terms and conditions text and save the builder. When yourerun the model, you should see that the contents of the NewMessage input have been added tothe terms and conditions page.

After you have tested your model, you should rebuild the application and test it on the por-tal server as a portlet (for instructions on how to do this, see the example in Chapter 1). After youhave added the portlet to a page in the portal, your portlet should appear as shown in Figure 15.5.

Figure 15.5 The Information portlet.

Creating a NewModel Wizard

Now that you have successfully created a Page Control Builder, you will create a new model wiz-ard that adds the option to create information portlets in the New Model Wizard. This is a usefulfeature because it enables you to automatically build a model with certain builders in it, based ona template you create yourself. Any time you would like to create a new model based on the tem-plate, you have only to select it from the New Model Wizard.

Change the Builder Type of the builder call to Model-based wizard builder, which enablesyou to create new models based on your settings in the Builder Skeleton. For the Model Nameinput, specify chapter15/information, which links the custom builder to the informationmodel you created earlier. Change the Builder ID so that it reads com.ibm.builders.Infor-mation, which also populates the Builder Class input. It is a good idea to make this change, asthe default Builder Class will be taken from your model name, and the first letter of your modelname is a lowercase letter (standard Java naming practice is to use an uppercase letter for the firstletter of a Java class).

Change the Readable Name input to Information, the Category to Custom Builders, andthe Description to Creates an information portlet with a terms and conditions

Page 447: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

page. All of these inputs define how the new Information option displays in the New Model wiz-ard. Notice that there is a new input at the bottom of the main section called Builder Pages, whichyou can use to define a series of pages for your model wizard (similar to the pages you go throughwhen adding a service provider or consumer). In this example, you don’t need any extra pages, soleave this checkbox unchecked.

Finally, remove the Name input from the Builder Inputs section at the bottom of thebuilder, as there is no need for developers to name the builder itself (they will be asked to nameonly the model by virtue of the fact that you are using the Model-based wizard builder option).You can remove an input by right-clicking the input name and selecting Delete Row. Save thebuilder call when you are finished.

Testing the NewModel Wizard Builder

To test the new builder, create a new WebSphere Portlet Factory Model. Under the CustomBuilders heading, there should be a new option for Information, as shown in Figure 15.6. Selectthis option and press Next. Name the model on the next screen and click Finish. If you have con-figured the builder correctly, you will have a new model in your project based on the informationmodel template.

410 Chapter 15 Performance and Process Optimization

Figure 15.6 The Information option in the New Model Wizard.

Page 448: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Important Points 411

Summary

In this chapter, you learned about the different ways in which you can optimize the performanceof your WPF portlets. You learned about caching concerns, the proper use of Ajax and Dojo, dataset and profiling considerations, session size testing, and performance logging. You also learnedhow to optimize the portlet development process using custom builders, and you built a simpleinformation portlet using a custom page control and a custom model-based wizard.

Chapter 16, “More Techniques for Domino,” expands on the Domino example in Chapter 4and introduces some ways in which you can interact with Domino databases from a portlet.

Important Points

• If used sparingly, Ajax and Dojo can improve the performance and usability of yourapplications.

• The Cache Control builder can be used to cache the output of any action in your model.Many WPF builders have built-in caching capabilities as well.

• Extensive use of profiling can drain system resources, so limit profile use to what youabsolutely need. Cached information is profile-specific, so cache non-profiled models ifpossible.

• Speed up data set retrieval operations by fetching only the records that you need. Also,use WPF’s paging capabilities so that only a snapshot of the total data set is ever neededat one time.

• You can monitor your applications for performance using debug tracing (particularly themodelActions property) and by monitoring the serverStats.txt log.

• You can monitor session sizes in your application by setting the appropriate propertiesin the bowstreet.properties file, and then restarting your application server. Sessioninformation is written to the sessionSize.csv file.

• Custom builders enable you to extend WPF’s existing builder library with your ownreusable, wizard-based components. These builders consist of an XML definition fileand a set of Java classes.

• A builder coordinator class can be used to dynamically change a builder interfacedepending on developer input.

Page 449: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 450: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

413

C H A P T E R 1 6

More Techniques forDomino

This chapter outlines some of the ways in which common Notes functionality can be surfaced ina portlet using WebSphere Portlet Factory (WPF). These functions are an extension of the tech-niques discussed in Chapter 4, “Using Domino Data.” By the end of the chapter, you will under-stand several common approaches to implementing Notes functionality in WPF. You will alsocreate a sample application to demonstrate these approaches, and become aware of the variousmethods that WPF makes available to you through the Domino Data Access builder.

Both the models used in this chapter are available for download from ibmpressbooks.com/title/9780137134465 under the Chapter 16 folder (instructions for copying these files into yourproject are included in a readme.txt file in the same folder), although it is recommended that youbuild them yourself using the application developed in Chapter 4 as a starting point. If youhaven’t already set up your environment to link to the Suppliers.nsf database, you should followthe instructions in the beginning of Chapter 4.

The following topics are covered in this chapter:

• Adding common Notes functionality

• Domino data access methods

Adding Common Notes Functionality

Most Notes application developers are acquainted with the different techniques used to buildNotes applications, such as coding, scripting, GUI manipulation, and formula writing. Whenfaced with the prospect of porting Notes applications to a portal, then, the question of how to

Page 451: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

implement this functionality in a portlet inevitably arises. How do you run a Notes agent from aportlet? Can you use formulas in portlets?

This section discusses several useful techniques for surfacing some of the more commonNotes functionality in a portlet. The suppliers application built in Chapter 4 is used as a startingpoint for these modifications, so if you have not already completed the example in that chapter, itis recommended you set up a WPF project with these artifacts (you don’t need to walk throughthe whole example; just download the artifacts for Chapter 4 and configure your project accord-ing to the instructions in the “Configuring Your Environment” section of Chapter 4).

Note that the modifications in this chapter are independent of each other, so you don’t needto walk through each section in order (you can just skip the sections you aren’t interested in).Also, before you begin the examples in this section, ensure that you are using the suppliersSer-vice model as your service provider, rather than the suppliersStub model discussed at the end ofChapter 4.

Notes Formulas, Validation, and Translation

Notes formulas are an integral part of Notes development, and depending on the type of formulaused, there are a number of different ways to bring them across to a portlet. Column formulas inNotes views, for example, are automatically brought across into WPF when you use a DominoData Access builder call or Domino View & Form builder call. Form formulas, however, are alittle more nuanced. As you saw in the example in Chapter 4, computed for display fields are notautomatically brought across into WPF, so you need to evaluate their formulas and display theresults from within the WPF application. Similarly, even though computed fields are broughtacross into WPF, they are not evaluated according to the field’s formula in Notes.

There are a number of ways to approach these situations. First, WPF comes with a DominoFormula builder, which is a quick and easy way to evaluate a Notes formula and display theresults in a portlet. The downside of this builder is that it can’t send its output (the evaluatedNotes formula) through a service, which means that it has to exist in the service consumer ratherthan the service provider. This is usually undesirable, as it mixes the presentation tier (what is dis-played to the screen) with the model tier (the data itself); ideally, the field on the form should getits value from a service and should not have to worry about where the service is getting its datafrom. To implement a service-based approach to form formulas, then, you can use the evaluate-Formula method of the Domino Data Access builder. The formula is evaluated by a serviceprovider, and the results are then passed back to the service consumer, which displays the resultsto the screen. The example at the end of this section uses this approach.

Although formulas in computed and computed for display fields do not automaticallytransfer across into WPF, validation formulas do come across in the sense that the Notes form iscomputed when the form on the portlet is submitted. For example, when you submit the supplierform in WPF, the validation formula for the supplierName field on the Notes form is evaluated,and if the validation fails, an error is generated. You can then cater for these errors by writing val-idation routines in WPF to output appropriate information to the user (validating fields is coveredin Chapter 11, “Field Validation, Formatting, and Translation”).

414 Chapter 16 More Techniques for Domino

Page 452: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Field translation formulas, on the other hand, are not automatically transferred to WPF, andneither are the formulas specified in keyword lookups for form fields. In both of these cases, youneed to implement the Notes formulas in WPF. Translating field data is covered in Chapter 11,and keyword lookups are covered in the “Keyword Lookups” section at the end of this chapter.

Finally, Notes formula agents cannot be run directly from a WPF portlet, and you will needto recode these agents in either LotusScript or Java. LotusScript and Java agents can be run fromWPF portlets, and you can also recode them directly in WPF using the Java Domino API (usingJava in WPF is discussed in Chapter 8, “Using Java in Portlets”).

The rest of this section describes how to transfer the supplier rating functionality of theSuppliers.nsf database into your WPF application. The formula is evaluated in the serviceprovider and the results are published through the readSupplierRating operation, which is con-sumed by the service consumer and displayed when viewing or editing a supplier.

The following builders are added in this section:

• Comment (x2)

• Variable

• Service Operation

• Action List

• Text

Providing the readSupplierRating Operation

To add Notes formula functionality to your service provider, first make sure the suppliersServicemodel is the currently active model in your IDE, and then add a Comment builder call to the sup-pliersService model and name it Formula. Save the builder call when you are finished, and add avariable to the suppliersService model by adding a Variable builder call. Name the variable sup-plierRatingFormula. This variable will hold the formula that you want to evaluate (you canenter the formula into the service operation directly, although using a variable makes your modelclearer and easier to maintain). Set the type of the variable to String and enter the formula shownbelow into the Initial Value input. Save the builder call when you are finished.

currentYear := @Text(@Year(@Now));

returnsCount := @If(@IsError(@DbLookup(“”; “”;

“LookupReturns”;supplierName+currentYear; 1)); 0;

@Count(@DbLookup(“”; “”; “LookupReturns”;supplierName+currentYear; 1)));

@If(@IsNewDoc; “”;returnsCount < 1; “This supplier has an excellent rating.”;

returnsCount < 2; “This supplier has a good rating.”;

returnsCount < 3; “This supplier has an average rating.”;

returnsCount < 4; “This supplier has a poor rating.”;

“This supplier has a very poor rating.”)

Adding Common Notes Functionality 415

Page 453: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Add a service operation to the suppliersService model, and fill out the inputs as shown inFigure 16.1. This creates a new service operation called readSupplierRating, which runs the eval-uateFormula method of the suppliersServiceView Domino Data Access builder. The operationtakes two arguments: The first is the formula you specified in the previous step, and the second isthe UNID of the document you would like to retrieve the supplier rating for. Only the secondargument needs to be specified by the service consumer. Note that the Specify Input Values set-ting enables you to manually map operation inputs to inputs in the called action.

416 Chapter 16 More Techniques for Domino

Figure 16.1 Configuring the readSupplierRating service operation.

For the Operation Results section of the builder call, specify ‘Use structure from calledaction’ for the Result Structure Handling input and make sure the Result Field Mapping input isset to Automatic. This causes the service operation to take the structure of its results from theevaluateFormula method (which leads to a String value being returned). Save the builder callwhen you are finished.

The formula is returned from the readSupplierRating operation on the service provider. Youcan test the operation by running the model from your IDE, and then selecting readSupplierViewfrom the index test page. Copy one of the supplier’s universal identifiers (UNIDs), and then pressthe Back button to return to the index page. From the index page, select readSupplierRating andthen paste in the UNID into the arg2 field (you can leave the arg1 field blank, as it is automati-cally set in the Service Operation builder). Note that you do not need to copy the UNID first ifyou specify a UNID in the testing defaults for the readSupplierRating operation in the ServiceDefinition builder. Press the Submit Query button and you should see the results of the formulaevaluation returned. The results for Fred Jackson, for example, are shown in Figure 16.2.

Page 454: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Common Notes Functionality 417

Figure 16.2 Supplier rating for Fred Jackson.

Consuming the readSupplierRating Operation

The next step is to configure the service consumer so that it consumes the readSupplierRatingoperation. To do this, make sure the suppliers model is the currently active model in your IDE,and then add a Comment builder call to the suppliers model and name it Formula. Save thebuilder call.

Add an action list to the suppliers model and name it getSupplierRating. This actionlist calls the readSupplierRating service operation, passing in the UNID that was used to read thesupplier document, and returns the supplier’s rating. The action list will be run from builder callsyou are about to create.

To add the appropriate action to the action list, open the Select Action dialog and thenselect the suppliersReadSupplierRatingsWithArgs method under the Methods heading. In theDefine Method Call Arguments dialog that follows, leave the first argument blank but select theUNID used to read the supplier document from the Select Action dialog, as shown in Figure 16.3.Click OK to accept the argument, and then click OK again to accept the action. Save the buildercall when you are finished.

Figure 16.3 Selecting the UNID of the current document.

Page 455: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

418 Chapter 16 More Techniques for Domino

The next step is to call this action list and display the results in the portlet. You can do thiswith a Text builder call, and you will need to add one for each page you would like the formularesults displayed on. In this example, you add only the formula results to the detail page.

To add the formula results to the detail page, add a Text builder call to the suppliers modeland fill out the inputs as shown in Figure 16.4. This calls the getSupplierRating action list and dis-plays the results after the data table on the detail page for each supplier (the formula is evaluatedwhenever the detail page is opened for a supplier). Save the builder call when you are finished.

Figure 16.4 Adding formula results to the detail page.

The Notes formula for evaluating a supplier rating is retrieved from your service consumermodel via the service provider model, and displayed to the screen. The detail page for FrankJackson, for example, should display as shown in Figure 16.5 when the suppliers model is runfrom the IDE.

Page 456: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Common Notes Functionality 419

Figure 16.5 A detail page displaying the supplierRating.

Notes Agents

LotusScript and Java Notes agents (but not formula Notes agents) can both be used from WPFportlets. Using Notes agents from WPF has a number of benefits:

• Notes agents provide an easy way to implement business logic from WPF, especially forDomino developers and even more so when working with Domino data.

• You can reuse existing Notes agents with minimal rewriting.

• Domino developers who don’t know how to code in Java can use LotusScript agentsinstead of Java methods in WPF.

• Business logic in Notes agents is separated from the presentation layer of your applica-tion (your portlet in WPF).

• Notes agents can take advantage of Domino security.

However, there are some disadvantages as well:

• Notes agents create a reliance on a Domino server, which is usually undesirable, unlessthe Domino server is also used as a data source.

• Notes agents are fairly useless unless they’re employed to manipulate Domino data, asthey have no access to the context in which the portlet runs (the portal API, the WPFWebApp, and so on).

Page 457: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• If you use any Java methods in your applications (as often happens when implementingbusiness logic for non-Domino data sources), then your applications can become con-fusing if you use Notes agents as well.

• Notes agents cannot return values to the functions that call them.

• Notes agents run outside the jurisdiction of the portal server, so the portal server has nocontrol over them (apart from deciding whether they are run in the first place).

When faced with the task of implementing business logic in WPF, these points need to betaken into consideration as part of your development strategy. Writing business logic in Javamethods is the generally preferred approach when there are non-Domino data sources or Javaframeworks in place, as it provides the most flexibility for future development. However, Notesagents provide an effective alternative when working with Domino data, particularly if the agentshave already been written in Notes or if the developers writing the code are Notes developers.There is no hard and fast rule as to which approach is best, so the decision probably needs to bemade on a case-by-case basis for each environment.

The example that follows describes how to call the AddSupplierToMMDataSource-FromWPF Notes agent from a button on the supplier’s portlet. This agent is based on the code ofthe Add to Mail Merge Data Source button on the Supplier form, with only one or two minorchanges required to make the code run from WPF. The code will add the current contact’s detailsto a file called supplierMailMerge.dat on the users C drive, which can then be used as a datasource for mail merges. Because the changes to the code are very minor, using a Notes agent is aquick and easy solution for surfacing the Add to Mail Merge Data Source functionality. The agentfunctionality is provided by the service provider model and consumed by the service consumer.

The following builders are added in this section:

• Comment (x2)

• Service Operation

• Action List

• Button

Providing the addSupplierToMMDataSource Operation

To add Notes agent functionality to the service provider model, first sign the AddSupplierToMM-DataSourceFromWPF agent with a user who has access to run restricted agents on the server. Youcan do this by opening and saving the agent in the Domino Designer®, provided your user ID hasaccess to run restricted agents on the server. Otherwise, you can sign the agent with the Dominoserver’s ID by navigating to the Files tab in a Domino Administrator client and clicking the Sup-pliers.nsf database in the file list. Then, select Sign from the Database menu, as shown in Figure16.6. On the Sign Database dialog that follows, select the Active server’s ID radio button optionand press OK.

420 Chapter 16 More Techniques for Domino

Page 458: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Common Notes Functionality 421

Figure 16.6 Signing the supplier database.

Make sure the suppliersService model is the currently active model in your IDE. Add aComment builder call to the suppliersService model and name it Agent. Save the builder call,and then add a service operation builder call to the suppliersService model and fill out the ServiceOperation Properties and Operation Inputs sections of the builder call as shown in Figure 16.7.This calls the runAgent method of the suppliersServiceView Domino Data Access builder, pass-ing in the two arguments specified. The first argument is the name of the formula to call(AddSupplierToMMDataSourceFromWPF), and the second argument is a document UNIDpassed in from the service consumer. The formula is evaluated for the document UNID specifiedin the second argument.

Select No Results for the Result Structure Handling input in the Operation Results section,as no results are returned from running the agent. Make sure Automatic is specified for the ResultField Mapping input, and save the builder call when you are finished.

The agent can now be run from the addSupplierToMMDataSource operation on the serviceprovider. You can test the operation by running the model from your IDE, and then selectingreadSupplierView from the index test page. Copy one of the supplier’s UNIDs, and then press theBack button to return to the index page. From the index page, select addSupplierToMMData-Source, and then paste the UNID into the arg2 field (you can leave the arg1 field blank, as it ishard coded into the Service Operation builder). Press the Submit Query button and the agent runs.No results are returned, so when the screen reloads, it simply displays the Back button. However,if you check in the root of your C drive, you should have a file called supplierMailMerge.dat. Ifyou open this file, you should see various details for the document specified in the second argu-ment to the service operation. The results for Kate Tredeau, for example, are as follows:

“Tile Kingdom”,”Kate Tredeau”,”1 Park Place”

Page 459: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

422 Chapter 16 More Techniques for Domino

Figure 16.7 Configuring the service operation properties and inputs.

If you run the operation again, it appends information to the end of the file (you can resetthe results by deleting the file from the file system).

Consuming the addSupplierToMMDataSource Operation

The next step is to configure the service consumer so that it consumes the addSupplierToMM-DataSource operation. To do this, make sure the suppliers model is the currently active model inyour IDE. Add a Comment builder call to the suppliers model, and name the builder call Agent.Save the builder call when you are finished.

Add an action list to the suppliers model, name the action list addSupplierToMMData-Source, and then add two actions to the list as shown in Figure 16.8. This action list calls theaddSupplierToMMDataSource service operation, and then reloads the suppliers view page. Savethe builder call when you are finished.

Next, add a button to the supplier detail page, which will run the action list you just created.To do this, add a Button builder call and fill out the inputs shown in Figure 16.9. Note that theaction is only linked to; it does not generate a submit form event (which would raise an exceptionas there is no form to submit on the supplier detail page). Save the builder call when you are fin-ished configuring it.

Page 460: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Common Notes Functionality 423

Figure 16.8 Configuring the addSupplierToMMDataSource action list.

Figure 16.9 Configuring the addSupplierToMMDataSourceButton builder call.

Page 461: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

424 Chapter 16 More Techniques for Domino

It is now possible to run the addSupplierToMMDataSource Notes agent from the suppliersmodel. Test the model now from your IDE, and open up the details page for World of Tiles. Pressthe Add to Mail Merge Data Source button, and you will be returned to the suppliers view. Thisautomatically creates a .dat file on your local machine (or updates the file if it already exists) withinformation on World of Tiles, which you can use to run mail merges in a word processor. If youcheck in the C drive on your local machine, you should see a file called supplierMailMerge.dat.Open this file. The file contains details for World of Tiles as follows (in addition to any previousdetails you added to the file):

“World of Tiles”,”Jason Shearer”,”90 Centre Rd”

TIP

When creating Notes agents that are accessed from WPF portlets, there are a number ofimportant points to be aware of:

• The Runtime target in the agent properties dialog in the Domino Designer should beset to None.

• You can get a reference to the current document in WPF from the Notes agent by usingthe following script:Dim session As New NotesSession

Dim db As NotesDatabase

Set db = session.CurrentDatabase

Dim doc As NotesDocument

Set doc = db.GetDocumentByID(session.CurrentAgent.ParameterDocID)

• The Run as Web User option in the agent security settings does not have any meaningwhen the agent is invoked via Domino Internet Inter-ORB Protocol (DIIOP), and istherefore irrelevant in these scenarios (by default, WPF communicates with Domino byDIIOP).

The AddSupplierToMMDataSourceFromWPF agent provided with the Suppliers.nsf data-base should serve as a good template for creating future Notes agents in WPF.

Keyword Lookups

Keyword lookups are often used on forms in Notes to provide users with a prepopulated list ofoptions for field values. In the suppliers application, for example, the stockSupplied field has alookup to the Stock view, and because the Allow Values Not in List checkbox on the stockSup-plied field properties is not enabled, users can specify stock for a supplier only when that stock islisted in the database.

This functionality does not come across into WPF when using the View & Form builder,but there are two main options available for recreating the same functionality in your WPFportlets. The first is to use the Domino Keyword Lookup builder, which provides a list of values

Page 462: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

from a Notes view, profile document, or Notes formula. You can then add a Select builder call toyour model, which takes a list of values that users can select from and inserts it at a particular tagon a page. The list used by the Select builder comes from the results of the keyword lookup. Thisapproach is a quick and easy solution, but unfortunately, the Domino Keyword Lookup buildercall requires a builder with Domino access in the same model. Because of this, the presentationand model tiers of your application are mixed together. As an alternative, you can use a service-based approach, where the presentation tier (your service consumer) makes calls to the model tier(the service provider) to provide the keyword lookup via a Lookup Table builder call. It is a littlemore work, but this approach allows a clearer separation of components, and is easier to maintainin the long run.

The rest of this section provides an example of how to implement a service-based keywordlookup. The Stock view in the suppliers database will be used as the basis for the lookup, which isthen shown on the update and create pages of the supplier form. To simplify the example, thestockSupplied field referenced in the Domino database takes only a single value; if you changethis field to accept multiple values, you also need to write a Java routine that separates out eachvalue in the field (separated by the pipe (|) symbol) and then selects the appropriate values in thedropdown box. Working with Java is covered in Chapter 8.

The following builders are added in this section:

• Comment (x2)

• Domino Data Access

• Service Operation

• Lookup Table

• Data Field Modifier

Providing the readStockView Operation

To implement keyword lookup functionality in the service provider model, first make sure thesuppliersService model is the currently active model in your IDE. Add a Comment builder call tothe suppliersService model and name it Keyword lookup. Save the builder call.

Add a new Domino Data Access builder call to the suppliersService model by selectingDomino Data Access from the Builder Palette, and then pressing OK. Configure the builder callas shown in Figure 16.10. This connects to the Stock view rather than the Suppliers view. Don’tenable the Enable Document and Form Support checkbox under the Document Form Supportsection, as there is no need to enable document support; you just want to return the list of stockitems for a keyword lookup.

Save the builder call when you are finished.Next, add a Service Operation builder call to the suppliersService model. This service oper-

ation returns the list of stock items provided by the stockView Domino Data Access builder call.Fill out the Service Operation Properties and Operation Inputs sections of the builder call asshown in Figure 16.11.

Adding Common Notes Functionality 425

Page 463: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure 16.10 Configuring the stockView builder call.

426 Chapter 16 More Techniques for Domino

Figure 16.11 Configuring the service operation properties and inputs.

Fill out the Operation Results section of the builder by selecting Use Structure from CalledAction for the Result Structure Handling input, and Automatic for the Result Field Mappinginput. This specifies that the structure of the results should come from the DataServices/stockView/readTable action, which causes an XML list of stock items to be returned. Save thebuilder call when you are finished.

Page 464: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Adding Common Notes Functionality 427

The keyword lookup is now available from the readStockView operation on the serviceprovider. You can test the operation by running the model from your IDE, and then selecting read-StockView from the index test page. You should see a list of stock items, as shown in Figure 16.12.

Figure 16.12 Testing the readStockView service operation.

Consuming the readStockView Operation

You now need to configure the service consumer so that it consumes the readStockView opera-tion. To do this, make sure the suppliers model is the currently active model in your IDE. Add aComment builder call to the suppliers model and name it Keyword lookup. Save the buildercall.

Create a lookup table by adding a Lookup Table builder call to the model. Name the lookupkeywordLookup, and specify Data Service as the Data Source. In the Data Service input, selectDataServices/suppliers/readStockView from the Select Action dialog, and then type the textItem_Code into the Value Tag and Label Tag inputs. This retrieves a list of stock items from thereadStockView operation, and then creates a keyword lookup based on the Item_Code column.The Label Tag for each stock item—that is, the text displayed to users—is the Item_Code (forinstance, AB232, CT234), and the Value Tag for each stock item—the value that is stored for eachselection—is also the Item_Code. Although these tags are often the same, you might want to usea different field for the label if the value isn’t user friendly (for example, the value might just be anumeric index, which won’t make much sense to end users). Save the builder call when you arefinished.

The final step involves creating form inputs on the update and create pages so that users canspecify the stock supplied based on the keyword lookup (you need to add two separate forminputs, although you can add both at one time with the same builder). To do this, add a Data FieldModifier builder call to the model and name it stockSuppliedLookup. Then, in the Fieldsinput, specify the two form inputs as shown in Figure 16.13. Scroll down to the Field Settingssection and change the Lookup Table Used input to keywordLookup. Save the builder call whenyou are finished.

Page 465: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

428 Chapter 16 More Techniques for Domino

Figure 16.14 Testing the lookup view.

Categorized Views

Categorized views are data lists where one or more fields are used to group information together,and they can make your data easier to navigate. These views can be implemented in WPF usingthe Category View builder. In the example that follows, you add a screen for the Returns view inthe suppliers database, which is a view of returned stock categorized on the return date.

The following builders are added in this section:

• Comment (x2)

• Domino Data Access

• Service Operation

• View & Form

• Button (x2)

• Category View

Providing the readReturnsView Operation

To add categorized view functionality to the suppliers application, the first step is to configure theservice provider so that it provides an operation to access data from the Returns view. To start this

Figure 16.13 Adding lookups for the stockSupplied fields.

It is now possible to look up the stock view from the suppliers model. Test the model fromyour IDE, and press the Create Supplier button. You should see the output shown in Figure 16.14.Notice that the stockSupplied field displays as a drop-down list box with pre-populated valuesfrom the lookup view.

Page 466: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

configuration, open the suppliersService model from the Project Explorer view. Add a Commentbuilder call to the model and call it Category view. Save the builder call when you are finished.

Now add another Domino Data Access builder call to the model and call it returnsView.This builder call is used to access the Returns view in the Suppliers.nsf database. Type Returnsin the View Name input, and then change the Rows to Include input to All Rows. By default, WPFdoes not display categorized rows, so if you do not change this input, you need to specify the cat-egorized fields manually when you enable categorized view support in the service consumer.Save the builder call when you are finished.

Add a Service Operation builder call to the model, which is the public interface for serviceconsumers to retrieve information from the Returns view. Change the Data Service input to sup-pliersService to associate the operation with the suppliersService service, and then type read-ReturnsView as the Operation Name. Specify DataServices/returnsView/readTable for theAction To Call, which accesses the Returns list from the Domino Data Access builder call.

Make sure the No Inputs option is selected for the Operation Inputs section. The OperationResults section can be left with the default settings, as you will let the structure of the results bedefined by the Domino Data Access builder call. Save the builder call when you are finished.

If you test the service at this point and run the readReturnsView operation, you should see alist of returned documents, as shown in Figure 16.15.

Adding Common Notes Functionality 429

Figure 16.15 Testing the lookup view.

Consuming the readReturnsView Operation

The next step is to configure the service consumer to display the results of the readReturnsViewoperation. To do this, open the suppliers model from the Project Explorer view and add a Com-ment builder call to the model. Name the builder call Category view, and save it when you arefinished.

The suppliers model already has a Service Consumer builder call pointing to the suppli-ersService model, so it already has access to the new service operation for accessing returns

Page 467: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

information. However, you need to define an interface for using this information. Add a View &Form builder call to the model and name it returnsView. Specify DataServices/suppliers/read-ReturnsView as the View Data Operation, and disable the checkbox for Generate Main in theAdvanced section (if you don’t do this last step, you will get errors when you try to run the model,as you already have a main method defined in your other View & Form builder call, and you can’thave more than one in the same model). Save the builder call when you are finished.

TIP

Categorized views are intended as an alternative to pagination, and as a result, you cannotuse pagination on a view that is also categorized. When using categorized views, makesure the Paged Data Display input on the View & Form builder is not enabled. For moreinformation on pagination, see Chapter 5.

Next, you need to add some buttons to enable users to navigate between the Suppliers viewand the Returns view. Add a Button builder call to the model, and fill out the inputs as shown inFigure 16.16. This button displays only when the suppliers list is visible, and it runs thereturnsView_ShowResults method when pressed (this method first reloads the returns view bycalling the suppliersReadReturnsView operation, and then it displays the results on the screen).

430 Chapter 16 More Techniques for Domino

Figure 16.16 Configuring the switchToReturns builder call.

Now add a second Button builder call and fill out the inputs as shown in Figure 16.17. Thissecond button displays only when the returns list is visible, and it shows the suppliersView_ViewPage page. Notice that the second button does not load the supplier information from the

Page 468: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

service when it is pressed; this is because the supplier information is already loaded by the mainAction List, and there is no need to load it twice.

Adding Common Notes Functionality 431

Figure 16.17 Configuring the switchToSuppliers builder call.

Save the model when you are finished. If you run the suppliers model at this stage, thereturns view displays as an ordinary, noncategorized view. To add the collapsible twisties (small,clickable arrows) familiar to Notes users, you need to add a Category View builder call to yourmodel. Do this now, and name the builder call categorizeReturns. Specify the ContainerField input as [returnsView_ViewPage]returnsView_ViewPage/ViewData/Row, which appliesthe builder call to each row of the returns view. Also, make sure the Category Selection input isset to Use Domino Category Rows, which automatically sets the categories in the returns view asthey are specified in the returns view in Notes. Note that this setting does not work if the DominoData Access builder call that defines the view has the Document Rows Only option set for theRows to Include input. Also, make sure the Span Columns input is disabled to prevent categoryfields from becoming merged together. Save the builder call when you are finished.

TIP

Even if you do not use a view that is categorized in Notes, you can still categorize the viewin WPF by selecting the Specify One or More Columns by which to Group the Data optionfor the Category Selection input. This brings up a list of each column in the view andenables you to set which column(s) should be categorizable.

Page 469: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Removing Unwanted Fields from the Returns View

By default, the suppliersService service provides two additional fields (UNID and isDocu-mentRow) that you don’t need in this example, so you can remove them using your Data FieldModifier. In Chapter 4, you created a Data Field Modifier called hideUnwantedFields, which youcan use to hide the rows in the Returns view. Open this Data Modifier builder call and add the tworows shown in Figure 16.18.

432 Chapter 16 More Techniques for Domino

Figure 16.18 Adding fields to the Data Field Modifier builder call.

Before you save the builder call, you need to move the Data Field Modifier so that it canaccess the results of the returnsView View & Form builder call (Data Field Modifiers must followthe builder calls that create the fields that they act upon). Select both the Modifiers Commentbuilder call and the hideUnwantedFields builder call, and drag them into the white space at thebottom of the model. Save the model when you are finished.

It is now possible to access the Returns view as a categorized view from the suppliersmodel. If you test the model now, you should see the output shown in Figure 16.19.

Figure 16.19 Testing the suppliers model.

Notice that there is a button on the page to switch to the Returns view. If you press this but-ton, the Returns view should display. You should be able to expand and collapse category sections

Page 470: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

in this view by clicking on the appropriate twisty icons (the small green arrow next to each cate-gory), as shown in Figure 16.20.

Adding Common Notes Functionality 433

Figure 16.20 Testing the categorized view.

Hide-When Fields

In Domino development, hide-when fields are often used to hide fields (or entire sections) of aform based on the values of certain fields. In WPF, the best way to do this is to use the VisibilitySetter, which lets you hide sections of a form based on another field value. The hide condition isevaluated only when the relevant section of the page is refreshed, so you don’t necessarily have torefresh the entire page (many builders contain a Post-Action Behavior section that lets you per-form partial page refreshes. Partial page refreshing is covered in Chapter 13).

To refresh all or part of the page, you may also need to use an HTML Event builder to act asthe trigger for the page refresh. For example, you can link an HTML Event builder call to theonChange event of a particular text field, and then tell the builder to refresh part of the page everytime the event is fired. So, every time the text field changes, the fields in the refreshed part of thepage may disappear or reappear, depending on the conditions specified in the Visibility Setter.

An example of hiding portions of a page without refreshing the entire page is provided inChapter 13.

Rich Text

Rich text is a popular format for storing formatted text in Notes and can also be used to storeattachments. You can display Notes Rich Text in WPF by enabling the Retrieve Rich Text Itemsas HTML input in the Domino Data Access builder, although note that this is specifically forNotes Rich Text fields, and not for Notes fields that contain HTML text (when displaying HTMLtext, you can use an ordinary Text builder in WPF, but make sure the Text Format input is set toAllow HTML Formatting of Text).

There is no native support in WPF for editing Notes Rich Text, however you can emulateNotes Rich Text edit functionality to some degree. For example, if you store your fields as HTML

Page 471: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

434 Chapter 16 More Techniques for Domino

in Notes, then you can use a combination of HTML tags and the Dojo Rich Text Editor widget todisplay and edit them. This is not perfect Rich Text functionality (it does not, for example, enableyou to attach files), but it may be suitable if you just want to use formatted text, as well as famil-iar HTML elements such as tables, images, and links. Attaching files is discussed in the next sec-tion.

The use of the Dojo Rich Text Editor is beyond the scope of this book, but an example isavailable for download from the WebSphere Portlet Factory wiki at www.ibm.com/developerworks/wikis/display/PortletFactoryID/IBM+-+Dojo+Rich+Text+Editor+sample. Formore information on the Dojo toolkit and its use in WPF, see Chapter 13.

Attachments

You can use the Domino Attachment builder call in WPF to convert all of the attachments in a doc-ument into clickable links on the page, which gives users an interface to launch attachments fromyour portlets. You can then place a Browse button on the page to upload files using the File Uploadbuilder, and copy the uploaded file into Domino via a Java method. For example, you can write anAction List that gets executed when you submit a form in WPF. This would run a Java method thatwould get a reference to the uploaded file (using the java.io.File class), and then it would copy thefile into a Rich Text item in the appropriate document (using the Domino Java API).

There are a few caveats with this process, however. The File Upload builder may not besupported by certain portal server versions if they are part of a JSR-168 portlet application (how-ever, version 6.x and later of WebSphere Portal fully support the use of the builder). Also, in orderto use the Domino Attachment builder, it is necessary to link to a Domino View or Domino View& Form builder, and both of these builders mix your presentation layer with your data layer. Thismight be undesirable if you are trying to maintain a clean break between these layers in yourapplication.

Attaching Domino documents is beyond the scope of this book, but for more informationon using Java in WPF, see Chapter 8 of this book.

Domino Data Access Methods

The Domino Data Access builder provides a number of useful methods for accessing and manip-ulating Domino data. You can access these methods from a Select Action dialog of any model thatcontains a Domino Data Access builder call. For example, in the suppliersService model, you canpress the ellipsis button next to the Action To Call input on any Service Operation builder call;this opens the Select Action dialog. Then, expand the Methods category and scroll down to thename of the Domino Data Access builder call (suppliersServiceView in the example). Each ofthese methods can be made available in a service provider, and the results can then be consumedfrom a service consumer. These method calls can also be inserted into other methods, which areuseful for methods such as getDominoSession (this gives you access to the Domino Sessionobject for the current user).

Page 472: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Domino Data Access Methods 435

TIP

The Domino Data Access methods are also available from the Domino View & Form builder,which is an amalgamation of the Domino Data Access builder and View & Form builders. It isrecommended that you use the Domino Data Access builder rather than the Domino View &Form builder, as it encourages separation of your presentation and model tiers.

The runAgent and evaluateFormula methods have already been discussed in this chapter, ashave the numerous methods used for basic interactivity with the supplier database (createDocu-ment, deleteDocument, and so on). However, there are a number of other useful methods that youshould be aware of, as discussed in the following sections.

getDominoSession() and getDominoDatabase()

The getDominoSession() and getDominoDatabase() methods provide you with access to the Ses-sion and Database objects, respectively (the Java versions of the NotesSession and NotesData-base objects). These methods are useful in Java methods when you want to access and manipulateDomino data; as any Domino developer will know, after you have access to these two objects,you can get references to just about every object in Domino (documents, views, and so on).

setComputeWithFormEnabled(boolean)

This method enables you to toggle whether Notes forms are computed when the equivalent WPFform is submitted, which is more useful than it may at first seem. By default, the validation for-mulas on a Notes form are calculated when the form is submitted in WPF, but being able to turnthis off saves you from having to recreate custom forms in Notes when you don’t want to use theNotes validation in WPF. This also enables you to use alternative methods of validation, such asthat provided by some of the default validation builders. Validation in WPF is discussed in moredetail in Chapter 11.

getUserName()

The getUserName() method can be useful when you want a string that names the current Notesuser being used to authenticate with the Domino server from WPF. If you leave the default valueof the Runtime Credentials input on the Domino Data Access builder (that is, ‘Use regen creden-tials specified above’), then the user that is specified in the Domino Server properties file isreturned from this function. Otherwise, the returned value differs depending on the value of theRuntime Credentials input.

sendDocument(IXml, boolean, boolean) and getDocumentData(String)

The sendDocument method enables you to send a Notes document via an email message, and itaccepts three arguments. The first is an IXml representation of the Notes document that you wantto send, the second argument specifies whether you want to save the document before it is sent,

Page 473: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

and the third specifies whether you want to attach the Notes form to the email message (note thatif you set both Boolean arguments to true, the form will be saved as part of the document). TheIXml used for the first argument is a WPF interface used to manipulate XML documents (for moreinformation on the IXml interface, see Chapter 9, “Using Web Services and ManipulatingXML”). You can create the IXml argument for the sendDocument function by using the getDocu-mentData function, which returns an IXml object. The getDocumentData method takes one Stringargument, which is the UNID of the document that you would like an IXml representation of.

Summary

In this chapter, you learned about implementing common Notes functionality in WPF, includingformulas, keyword lookups, agents, categorized views, hide-when fields, rich text, and attach-ments. The application built in this chapter provided this functionality by expanding on the sup-pliers application built in Chapter 4. You also learned about some of the different methodsavailable to you via the Domino Data Access builder.

Important Points

• The Domino Data Access builder and Domino View & Form builder contain a numberof Java methods for interacting with Domino data. It is usually preferable to use DominoData Access builder calls rather than Domino View & Form builder calls, as they enableyou to separate your presentation tier from your model tier.

• Calling the evaluateFormula method of the Domino Data Access builder in a ServiceOperation is the preferred method for using Notes formulas in WPF. The Domino For-mula builder also enables you to perform this function, but it does not enable you to sep-arate the presentation tier from the model tier.

• Notes procedures can be run in WPF by either recoding them in Java (using the JavaDomino API) or including them in Notes agents, which are then run using the runAgentmethod of the Domino Data Access builder. When running Notes agents in WPF, theRuntime target setting in the agent properties should be set to None. The Current-Agent.ParameterDocID method of the NotesSession class can be used to get a referenceto the current document in the Notes agent.

• Using a Lookup Table builder call in a service provider model is the preferable methodfor emulating keyword lookup functionality in WPF. The Domino Keyword Lookupbuilder also enables you to perform this function, but it does not enable you to separatethe presentation tier from the model tier.

• Categorized views can be implemented in WPF using the Category View builder. Notethat the categorization is intended as an alternative to pagination, so you should notapply both to the same view.

436 Chapter 16 More Techniques for Domino

Page 474: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• The best way to implement Notes hide-when functionality in WPF is to use the Visibil-ity Setter builder. This builder can be used in conjunction with Ajax to perform partialpage refreshes that simulate the use of hide-when fields in a Notes client.

• There is no native support in WPF for editing Notes Rich Text fields, but you can emu-late this functionality using the Dojo Rich Text Editor widget and HTML fields. You canenable rich text fields to be displayed in WPF by enabling the Retrieve Rich Text Itemsas HTML input in the Domino Data Access builder.

• The Domino Attachment builder can be used to convert all of the attachments in a docu-ment into clickable links on a page. The File Upload builder provides a file upload but-ton on a form.

Important Points 437

Page 475: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 476: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

439

A P P E N D I X A

Setting Up YourEnvironment

This appendix provides instructions for setting up your environment to use WebSphere® PortletFactory. You should step through this appendix like a checklist, making sure you have completedall the relevant steps for your own environment. You can skip sections if they are irrelevant to theapplications you’re building (for example, you can skip the section on Lotus Domino if youaren’t planning on completing any of the examples that use it) and come back to them later if youchange your mind.

The following points are covered in this appendix:

• Installing WebSphere Portlet Factory

• Configuring WebSphere Portal

• Configuring Lotus Domino

• Creating a test database in DB2

• Creating a test database in SQL Server

• Configuring a JDBC resource

Installing WebSphere Portlet Factory

If you have already installed WPF, you can skip this section. After you have obtained a copy of WPF (WPF 6.0.2 is available for purchase and download

from the IBM site at www-306.ibm.com/software/genservers/portletfactory/), you can installWebSphere Portlet Factory by following these steps:

1. Unzip the WPF install files into a temporary directory on your machine.

2. Double-click the install.bat file to start the install wizard.

Page 477: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

3. Select your language from the first screen in the wizard, and then click OK.

4. Depending on the install file version you have, you may get some introductory infor-mation on the next screen. Click Next.

5. The next screen asks you to accept the license agreement. Click ‘I accept the terms ofthe License Agreement’ and then click Next.

6. Type in a new pathname if you don’t want to install WPF into the default install path.Press Next when you are finished.

7. On the next screen, the install wizard asks you to specify which software you wouldlike to install. WPF installs into an Eclipse-based IDE, so you can either install WPFinto an existing Eclipse installation, or you can install a new copy of Eclipse when youinstall WPF (version 3.2.2 of Eclipse is included with WPF 6.0.2). Press Next whenyou are finished.

8. On the next screen, you need to verify the IDE you would like to install WPF into. Ifyou choose to install WPF into an existing copy of Eclipse, you will be prompted toverify its location in the file system (it must be the same version of Eclipse). If youchoose to install WPF into Rational Application Developer, Rational Software Archi-tect, or Rational Web Developer, you will be prompted to select the appropriate instal-lation from a list box. Otherwise, you need to verify the install path for your newinstallation of Eclipse. Press Next when you are finished.

9. The next screen asks whether you would like to install WebSphere Application ServerCommunity Edition (WAS CE) as a development test server. WAS CE is a lightweightversion of the WebSphere Application Server (WAS) and is ideal for testing because itis much faster than a full-blown install of WAS. Unless you prefer an alternative setup,it is recommended you click the checkbox to install WAS CE.

10. If you opted to install WAS CE on the previous screen, this next screen prompts youfor the install location. Change the path if desired, and then press Next.

11. The next screen displays a summary of your settings. Verify that your settings are cor-rect, pressing the Previous button to navigate back through the wizard if required. If allof your settings are correct, press Install to begin installing WPF.

12. After WPF has finished installing, you should see a success message similar to the oneshown in Figure A.1. Click Done to close the install wizard, which then opens a pagein your default Web browser that contains a brief introduction to WPF.

You have now successfully installed WPF. You can start the WPF Designer (that is, theEclipse IDE with WPF installed into it) by pressing the Start button in Windows, and then select-ing IBM WebSphere, Portlet Factory, Designer from the Programs menu.

440 Appendix A Setting Up Your Environment

Page 478: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Configuring WebSphere Portal 441

Figure A.1 Success message in the install wizard.

Configuring WebSphere Portal

If you already have a target page on the portal for your portlets and you have access to deployportlets to the portal server, you can skip this section.

To follow the examples in this book, you need to set up a target page (or several pages) toadd your portlets to. It is assumed that you already have a portal server installed and available foryou to use; if this is not the case, you need to set this up first (WebSphere Portal 6.0 is usedthroughout this book).

There are no restrictions on the page(s) you use, although if you’re deploying to a test por-tal server, it makes testing faster if you use the Welcome page or a page that is easily accessiblefrom the Welcome page. If you’re using an existing portal page as a target page, no additionalconfiguration should be necessary, unless you don’t have access to add portlets to that page. Ifthis is the case, skip to the “Setting Up Access” section in this chapter.

Note that the steps in this section may differ slightly depending on the version of Web-Sphere Portal you use (the steps in this section cover WebSphere Portal 6.0).

Setting Up a New Target Page

To set up a new target page for your portlets, log in to the portal with a user who has access to adda page to the portal. If you do not have sufficient access, skip to the “Setting Up Access” section.After you are logged into the portal, navigate to the administration page from the Launch menu.

Page 479: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

On the administration page, press the Manage Pages link, as shown in Figure A.2.

442 Appendix A Setting Up Your Environment

Figure A.2 Selecting the Manage Pages link.

When the Manage Pages portlet displays, you need to navigate to where you want to addthe new page. Select Content Root, and then select Home. The Manage Pages portlet now lists thepages contained in the topmost menu in the portal. You can add a page to this menu by pressingthe New Page button. Alternatively, you can add a page to a different part of the portal (such asthe Welcome page) by navigating to that page in the Manage Pages portlet, and then by pressingthe New Page button.

After you press the New Page button, the Page Properties portlet displays. Give your newpage a title (for example, WPF Test Page). Press the OK button to save the new page and return tothe Manage Pages portlet.

The new page should display as shown in Figure A.3.

Figure A.3 The new page displayed in the Manage Pages portlet.

Page 480: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Leave the administration page by selecting Home from the Launch menu. You have nowsuccessfully added a page to the portal. Additional pages can be added through the same process.You can navigate to the page you just created by selecting it from the page navigation menu (if itis not immediately visible, you may need to navigate to its parent page first).

Setting Up Access

Other than setting up a target page, you should make sure that you have access to add portlets tothe target page and that you have access to deploy applications to the server. If you don’t have thisaccess, you have to give your Web Application Archive (WAR) files to an administrator so that hecan deploy them and add them to the portal for you—a highly undesirable arrangement in a testenvironment, but a common occurrence in production environments (where it is assumed that theupdates are less frequent).

The best way to get all the required permissions is to use an administrator account—that is,a user (such as the wpsadmin user, which is normally set up when installing the portal) who is amember of the administrators group in the portal (usually called wpsadmins). If you are unable toget an administrator account, you may be able to request an administrator to assign you theappropriate access in an ordinary user account. In WebSphere Portal, the access levels you needare as follows: at least Privileged User access to the Pages resource if you’re going to add yourpage to a private page, or at least Editor access to the Pages resource if you’re going to add yourpage to a shared page. To deploy and update your applications, you need to have Manager accessto the Web Modules resource.

If you can’t get the appropriate access, you need to get an administrator to deploy and addyour portlets to the portal. In this case, it is worthwhile to set up a local portal server for testing. Ifthis is not possible, then you should set up a local application server, which you can use to testyour portlets as ordinary Web applications (although note that you won’t be able to test any fea-tures offered by the portal itself—such as inter-portlet communication—until you’ve deployedthe application to a portal server). The WAS CE install that comes with WPF is a perfect candi-date for this.

Configuring Lotus Domino

If you do not intend on building any applications that require a Lotus Domino server (such as theexample discussed in Chapter 4, “Using Domino Data”), you can skip this section.

Several steps are required to set up communication between WPF and a Domino server:

1. Start the Domino Internet Inter-Orb Protocol (DIIOP) and HTTP tasks.

2. Enable HTTP clients to browse databases.

These steps are covered in the following sections. (It is assumed that you already have aDomino server installed and the Domino Designer and Domino Administrator clients. Release 6or later is recommended for both the Domino server and the clients.)

Configuring Lotus Domino 443

Page 481: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Start the DIIOP and HTTP Tasks

WPF uses DIIOP to communicate with Domino by default, although you can specify to useHTTP instead. To use them, both of these protocols require a corresponding task to run on theDomino server.

Domino servers earlier than version 6.x require you to have both tasks running; otherwise,you need to enable only one or the other. It is useful, however, to have both tasks running regard-less of the version you use, so that you can use the connectivity test page provided by WPF (thistest page is discussed in Chapter 4). This section describes how to start both tasks.

TIP

During development, you can configure which port you want to use for Domino connectivityin WPF via the Use HTTP Access field of the Domino Data Access builder.

To start the DIIOP and HTTP tasks on the Domino server, complete these steps:Using a text editor such as Notepad, open the notes.ini file for the server you want to use to

communicate with WPF. The notes.ini file is located in the root directory of your Domino serverinstallation (for example, C:\Program Files\Domino).

Do a search for the text, “servertasks”. The result of the search should show a line similar tothe following:

ServerTasks=Update,Replica,Router,AMgr,AdminP,CalConn,Sched

Change this line to include entries for HTTP and DIIOP, as shown in the following example(note that if there are already entries for HTTP and DIIOP, there is no need to add them again):

ServerTasks=Update,Replica,Router,AMgr,AdminP,CalConn,Sched,

�DIIOP,HTTP

Save and close the notes.ini file. Doing so loads the HTTP and DIIOP tasks the next timeDomino starts.

To load the HTTP and DIIOP tasks, you can either restart the Domino server (by typingrestart server at the Domino console) or type the following commands into the Dominoconsole: load HTTP and then load DIIOP. You can stop these tasks by using the commandstell HTTP quit and tell DIIOP quit (if you want to stop them from being loaded when theserver restarts, take the corresponding entries out of the ServerTasks line from the notes.ini file).

Enable HTTP Clients to Browse Databases

Enabling HTTP clients to browse databases enables you to browse the databases on the serverfrom within the WPF Designer (you need to complete this step even if you use DIIOP instead ofHTTP).

444 Appendix A Setting Up Your Environment

Page 482: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

To enable HTTP clients to browse databases, first open up the Domino Administrator clientand make sure it points to the server that will communicate with WPF. You can change this serverby selecting Open server from the File menu. If you don’t have the Administrator client installed,open a Lotus Notes client, and then open the names.nsf database on the server that will communi-cate with WPF.

Open the server document for the server that will communicate with WPF. If you use theAdministrator client, this should be done by clicking Current Server Document on the Configura-tion tab, as shown in Figure A.4.

Configuring Lotus Domino 445

Figure A.4 Opening the server document from the Administrator client.

If you use the Administrator client, open the server document by double-clicking the serverdocument from the All Server Documents view, as shown in Figure A.5.

Figure A.5 Opening the server document from the Notes client.

Press the Edit Server button at the top of the document to edit the server document, andthen navigate to the Internet Protocols tab. Scroll down to the R5 Basics section, and make surethe setting ‘Allow HTTP clients to browse databases’ is set to Yes (note that this should still bedone, even if you use a release of Domino later then R5). Save and close the server document.

Restart the server by typing restart server at the Domino console.Your Domino environment is now configured and should be accessible from WPF. Chapter

4 discusses how to set up a WPF project to connect to a Domino server.

Page 483: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Creating a Test Database in DB2

The rest of this appendix concerns the application discussed in Chapter 3, “Using Data from aRelational Data Source.” If you do not intend to build the Chapter 3 example, you do not need toread the rest of this appendix. Complete the steps in this section if you intend to build the applica-tion discussed in Chapter 3 and if you want to connect to a DB2 database. If you intend to buildthis application but want to use an SQL Server database instead, skip to the next section, “Creat-ing a Test Database in SQL Server.”

This section covers how to create a DB2 database for the example in Chapter 3. This data-base will contain a list of basic contact information. There is no strict requirement that you usethis particular database, so feel free to use another database if desired (but note, of course, thatcertain steps in the example will need to be adjusted accordingly). There is no restriction onwhether the DB2 server is installed locally or remotely to your application servers and portalservers.

To create the contacts database in DB2, first start the DB2 Command Editor from the Startmenu in Windows, and then copy and paste the contents of DB2TESTDB.sql file into the topmostedit pane in the Command Editor (you can obtain this file from the Appendix A folder at ibm-pressbooks.com/title/9780137134465). If you do not have access to the DB2TESTDB.sql file,copy the following text into the Command Editor:

— Create and connect to database

CREATE DATABASE TESTDB;

CONNECT TO TESTDB;

— Create contacts table

CREATE TABLE “ADMINISTRATOR”.”CONTACTS” (

“ID” INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY

(START WITH 1, INCREMENT BY 1),

“FIRSTNAME” VARCHAR(15) NOT NULL,

“LASTNAME” VARCHAR(15) NOT NULL,

“COMPANY” VARCHAR(20),

“ADDRESS” VARCHAR(30),

“PHONE” VARCHAR(15),

“EMAIL” VARCHAR(30),

“FAX” VARCHAR(15) )

IN “USERSPACE1”;

COMMENT ON TABLE “ADMINISTRATOR”.”CONTACTS” IS ‘A list of

�contacts used to test use of DB2 in WPF’;

ALTER TABLE “ADMINISTRATOR”.”CONTACTS”

ADD CONSTRAINT “CONTACT_ID” PRIMARY KEY (“ID”);

COMMIT;

446 Appendix A Setting Up Your Environment

Page 484: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

— Add contact records

INSERT INTO “ADMINISTRATOR”.”CONTACTS” (FIRSTNAME, LASTNAME,

ADDRESS, COMPANY, PHONE, EMAIL, FAX) VALUES

(‘Bob’, ‘Jones’, ‘12 Elm St’, ‘Bobs Plumbing’, ‘555-2323’,

‘bob@bobs_plumbing.com’, ‘555-2333’),

(‘Sally’, ‘Williams’, ‘23 Millewa Ave’, ‘Acme Co.’,

‘747-7767’, ‘[email protected]’, ‘747-7769’),

(‘James’, ‘Cummings’, ‘46 Church Rd’, ‘Ties r Us’, ‘555-1187’,

[email protected]’, ‘555-1180’),

(‘Haley’, ‘Smith’, ‘46 Church Rd’, ‘Ties r Us’, ‘555-1188’,

[email protected]’, ‘555-1180’),

(‘Patrick’, ‘Johnson’, ‘23 Millewa Ave’, ‘Acme Co.’,

‘747-7768’, ‘[email protected]’, ‘747-7769’);

COMMIT;

CONNECT RESET;

TERMINATE;

Before you execute the script, substitute the four occurrences of the word ADMINISTRA-TOR with a user who has access to create databases, add tables, and insert records on the DB2server.

Press the button to execute the SQL script. Running the script creates a DB2 databasecalled TESTDB. It contains a table called CONTACTS. The columns in the CONTACTS tablecontain various items of information about each contact, including an automatically generatedprimary key (that is, a value that uniquely identifies each contact). The script also adds five con-tacts to the table.

The results of running the SQL script display in the bottom pane of the Command Editor.Scroll through the results and ensure they indicate that each command was performed success-fully—if this is not the case, make sure you entered the SQL script correctly and that you haveenough access to create new databases and tables. You can test whether the script worked byselecting TESTDB from the Target dropdown and by typing the following SQL into the Com-mand Editor (substituting the name ADMINISTRATOR with the name you used earlier):

SELECT * from “ADMINISTRATOR”.”CONTACTS”

Press the button and you should receive the output shown in Figure A.6.You now have a database you can use to complete the example in Chapter 3, but you need

to add a JDBC resource for it before you can use it in WPF (unless you are using WAS CE, inwhich case, you need to set up a database pool instead. Setting up a database pool is covered inthe Reference, WAS CE Reference and Troubleshooting section in the WPF Designer help). Ifyou are not using WAS CE, skip to the “Configuring a JDBC Resource” section at the end of thisappendix.

Creating a Test Database in DB2 447

Page 485: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure A.6 Testing that the SQL script worked correctly.

Creating a Test Database in SQL Server

Complete the steps in this section if you intend to build the application discussed in Chapter 3 andyou want to connect to an SQL Server database. If you intend to build this application but want touse a DB2 database, complete the previous section instead.

This section covers how to create an SQL Server database for the example in Chapter 3.This database contains a list of basic contact information. There is no strict requirement that youuse this particular database, so feel free to use another database if desired (but note, of course, thesteps that refer to the database in the example will need to be adjusted accordingly). There is norestriction on whether the SQL Server is installed locally or remotely to your application serversand portal servers.

To create the contacts database in SQL Server, run the SSTESTDB.sql script on a machinewith the SQL Server Management Studio installed by double-clicking the SSTESTDB.sql file(you can obtain this file from the Appendix A folder at ibmpressbooks.com/title/9780137134465). If you do not have access to the SSTESTDB.sql script, you should create anempty file with the same name and copy in the contents shown below (save the file and run itwhen finished):

— Create database

USE [master]

GO

CREATE DATABASE TESTDB

GO

USE [TESTDB]

GO

448 Appendix A Setting Up Your Environment

Page 486: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

BEGIN TRANSACTION

GO

CREATE TABLE [ADMINISTRATOR].CONTACTS

(

ID int NOT NULL IDENTITY (1, 1),

FIRSTNAME varchar(15) NOT NULL,

LASTNAME varchar(15) NOT NULL,

COMPANY varchar(20) NULL,

ADDRESS varchar(30) NULL,

PHONE varchar(15) NULL,

EMAIL varchar(30) NULL,

FAX varchar(15) NULL

) ON [PRIMARY]

GO

ALTER TABLE [ADMINISTRATOR].CONTACTS ADD CONSTRAINT

CONTACT_ID PRIMARY KEY CLUSTERED

(

ID

) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,

ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

GO

—Add contact records

INSERT INTO [ADMINISTRATOR].CONTACTS ([FIRSTNAME],[LASTNAME],

[COMPANY],[ADDRESS],[PHONE],[EMAIL],[FAX])

SELECT ‘Bob’, ‘Jones’, ‘12 Elm St’, ‘Bobs Plumbing’,

‘555-2323’, ‘bob@bobs_plumbing.com’, ‘555-2333’ UNION ALL

SELECT ‘Sally’, ‘Williams’, ‘23 Millewa Ave’, ‘Acme Co.’,

‘747-7767’, ‘[email protected]’, ‘747-7769’ UNION ALL

SELECT ‘James’, ‘Cummings’, ‘46 Church Rd’, ‘Ties r Us’,

‘555-1187’, ‘[email protected]’, ‘555-1180’ UNION ALL

SELECT ‘Haley’, ‘Smith’, ‘46 Church Rd’, ‘Ties r Us’,

‘555-1188’, ‘[email protected]’, ‘555-1180’ UNION ALL

SELECT ‘Patrick’, ‘Johnson’, ‘23 Millewa Ave’, ‘Acme Co.’,

‘747-7768’, ‘[email protected]’, ‘747-7769’

GO

COMMIT

Creating a Test Database in SQL Server 449

Page 487: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

After you run the SSTESTDB.sql script, you are prompted to authenticate with SQLServer—make sure your server settings are correct and press the Connect button to connect to theserver and open the SQL Server Management Studio.

Before you execute the script, you need to change the three occurrences of the wordADMINISTRATOR to the name of a user who has access to create databases, add tables, andinsert records on the SQL Server. When you have finished making these changes, press F5 to exe-cute the SQL script.

Executing the script creates a SQL Server database called TESTDB; it contains a tablecalled CONTACTS. The columns in the CONTACTS table contain various items of informationabout each contact, including an automatically generated primary key (that is, a value to uniquelyidentify each contact). The script also adds five contacts to the table.

The results of running the SQL script display in the Messages tab in the bottom pane of theManagement Studio. You should get a message saying that five rows were affected (these are thecontacts you added to the CONTACTS table). Make sure the results don’t include any error mes-sages (text printed in red). If you do get errors, check that you correctly changed the ADMINIS-TRATOR name to the name of a user that has sufficient access to complete all of the operations inthe SQL script.

You can test whether the script worked by pressing Ctrl+N to create a new query, selectingTESTDB from the database drop-down box on the toolbar, and then typing the following SQLinto the SQL editing pane (substituting the name ADMINISTRATOR with the name you usedearlier):

SELECT * from ADMINISTRATOR.CONTACTS

Press F5 to execute the script, and you should see the table structure in the Results tab ofthe Management Studio, as shown in Figure A.7.

450 Appendix A Setting Up Your Environment

Figure A.7 Testing that the SQL script worked correctly.

You now have a database that you can use to complete the example in Chapter 3, but youneed to add a JDBC resource for it before you can use it in WPF (unless you are using WAS CE,in which case you will need to set up a database pool instead. Setting up a database pool is cov-ered in the Reference, WAS CE Reference and Troubleshooting section in the WPF Designerhelp). The next section explains how to set up a JDBC resource.

Page 488: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Configuring a JDBC Resource

Complete the steps in this section if you intend to build the application discussed in Chapter 3 andyou have already created a contacts database. Note that if you use WAS CE, you need to set up adatabase pool instead, which is covered in the Reference, WAS CE Reference and Troubleshoot-ing section in the WPF Designer help.

To connect to a relational data source from WPF, you need to set up a JDBC resource for iton an application server (the JDBC resource is what you connect to from inside WPF). You canuse the server specified in either of your deployment configurations, but the JDBC settings on theserver specified in your application server deployment configuration are used to automaticallypopulate suggested options for some of the builder inputs, so it is recommended that you use thisserver.

To set up a JDBC resource on an application server, first open the administration consolefor the server on which you would like to set up the JDBC connection. For example, for a defaultconfiguration on a local portal server, you might use https://localhost:10039/ibm/console/.

TIP

In a WebSphere Portal installation, both the server1 and WebSphere_Portal instance havecorresponding administration consoles. Although the exact URLs might differ depending onyour configuration, the administration consoles can usually be accessed by adding one tothe port number and changing the protocol to use https. For example, this address:

http://localhost:10038/wps/portal

would become:

https://localhost:10039/ibm/console/

After the administration console has opened, navigate to the JDBC Providers link under theResources heading, as shown in Figure A.8.

Configuring a JDBC Resource 451

Figure A.8 Navigating to the JDBC Providers link.

Page 489: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Make sure the application server you want to use is listed in the Server box (you can spec-ify a server by clicking the Browse Servers button, selecting the server you want, and then press-ing OK). The driver providers available on that server will be listed below the server box.

If you already have a driver provider for the type of database you are connecting to (DB2 orSQL Server), click on the provider from the list and skip to the “Configuring the Driver” section.Otherwise, you will need to create a driver provider for the appropriate database type. Press theNew button as shown in Figure A.9. If you are setting up a driver provider for an SQL Serverdatabase, skip to the “Setting Up a SQL Server Driver Provider” section. If you are setting up adriver provider for a DB2 database, continue to “Setting Up a DB2 Database Driver Provider.”

452 Appendix A Setting Up Your Environment

Figure A.9 Creating a new driver provider.

Setting Up a DB2 Database Driver Provider

To set up a driver provider for a DB2 database, select DB2 as the database type. Then, select DB2Universal JDBC Driver Provider for the provider type, and Connection pool data source for theimplementation type. Click Next when you are finished.

The next screen enables you to configure details for the provider. Accept the defaults andpress OK. On the confirmation screen that follows, press the Save link, and then press the Savebutton on the screen that follows to save the new provider.

Page 490: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

The driver provider you just created will display in the driver providers list. Unless youchange the default name for the provider, the DB2 provider is called DB2 Universal JDBC DriverProvider. Click on the driver provider you just created, which opens the configuration page forthe provider.

Skip to the section “Configuring the Driver.”

Setting Up a SQL Server Driver Provider

To set up a driver provider for an SQL Server database, select SQL Server as the database type.Then, select WebSphere embedded ConnectJDBC driver for MS SQL Server for the providertype, and Connection pool data source for the implementation type. Click Next when you arefinished.

The next screen enables you to configure details for the provider. Accept the defaults andpress OK. On the confirmation screen that follows, press Save, and then press the Save button onthe screen that follows to save the new provider.

The driver provider you just created now displays in the driver providers list. Unless youchange the default name for the provider, the SQL Server provider is called ‘WebSphere embed-ded ConnectJDBC driver for MS SQL Server’. Click the driver provider you just created, whichopens the configuration page for the provider.

Configuring the Driver

On the provider configuration page, click the Data source link (under the Additional Propertiesheading), as shown in Figure A.10. This displays the data sources currently configured for theprovider.

Configuring a JDBC Resource 453

Figure A.10 Clicking the Data sources link.

The next step is to add a data source for the TESTDB database. To do this, first press theNew button as shown in Figure A.11.

Change the name, JNDI name, and description of the data source, as shown in Figure A.12.Note that the JNDI name has a jdbc/ prefix, which is required by WPF (WPF picks up JDBC datasources with the jdbc/ prefix only). If your provider is for a SQL Server database, skip to the“Configuring a SQL Server Data Source” section. If your provider is for a DB2 database, con-tinue to the next section, “Configuring a DB2 Data Source.”

Page 491: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure A.11 Creating a new data source.

454 Appendix A Setting Up Your Environment

Figure A.12 Setting the name, JNDI name, and description for the TESTDB data source.

Configuring a DB2 Data Source

Change the DB2 Universal data source properties, as shown in Figure A.13 (specifying a differ-ent hostname if your DB2 server is not on localhost). These settings define where to obtain theTESTDB database from. Press OK when you are finished.

The new data source for the TESTDB database should be listed as shown in Figure A.14.Press the Save link on the confirmation screen, then press the Save link on the screen that follows(as highlighted in Figure A.14) to save the data source settings. Skip to the “Configuring anAuthentication Mechanism” section when finished.

Page 492: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure A.13 Setting the DB2 Universal data source properties.

Configuring a JDBC Resource 455

Figure A.14 Saving changes to the data source.

Configuring a SQL Server Data Source

To configure the SQL data source, change the Connect JDBC data source properties, as shown inFigure A.15 (specifying a different hostname if SQL Server is not running on localhost). Thesesettings define where to obtain the TESTDB database from. Press OK when finished.

Page 493: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure A.15 Setting SQL Server data source properties.

The new data source for the TESTDB database should be listed as shown in Figure A.16.Press the Save link on the confirmation screen, then press the Save button on the screen that fol-lows (as highlighted in Figure A.16) to save the data source settings.

456 Appendix A Setting Up Your Environment

Figure A.16 Saving changes to the data source.

Configuring an Authentication Mechanism

The next step is to configure an authentication mechanism for the data source. Click the TESTDBdata source in the list, and then click the J2EE Connector Architecture (J2C) authentication dataentries link under the Related Items heading, as shown in Figure A.17.

Page 494: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Figure A.17 Specifying an authentication mechanism.

Click the New button to create a new authentication entry, then fill out the general proper-ties as shown in Figure A.18 (the username and password fields should correspond to a user thathas access to either the DB2 or SQL Server database). Press OK when you are finished.

Configuring a JDBC Resource 457

Figure A.18 Specifying credentials for the authentication mechanism.

Don’t save the authentication entry just yet—first open the TESTDB data source again byclicking the TESTDB link, and then scroll down to the ‘Component managed authenticationalias’ area. Select the authentication alias you just created from the dropdown, and then press OK.Press the Save link on the confirmation screen that follows, and then press the Save button to savethe data source.

You have now successfully created and configured a data source for the TESTDB database.If you are using a SQL Server database, you can skip to the “Testing the Data Source” section to

Page 495: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

test the data source. Otherwise, one final step that is required before you can test the data sourceis to make sure your DB2 environment variables are set correctly, as these will be used to locateyour DB2 drivers (DB2 environment variables are not set by default in WebSphere Portal 6). Todo this, navigate to the WebSphere Variables page, as shown in Figure A.19. On the next screen, ifthere is a server specified in the Server box, remove it and press the Apply button to make sureyou are looking at all the environment variables for the current node.

458 Appendix A Setting Up Your Environment

Figure A.19 Navigating to the WebSphere Variables page.

Scroll down through the list to find the DB2UNIVERSAL_JDBC_DRIVER_PATH envi-ronment variable, then make sure it points to a directory that holds a file called db2jcc.jar. Youcan find this file by searching for it on the machine running DB2 (by default, it is located in the\Program Files\ibm\SQLLIB\java directory). If you need to change an environment variable, youcan click on it in the list, change the Value field, and then press OK.

Your data source is now ready to test.

Testing the Data Source

To test your connection to the TESTDB data source, press the Test connection button, as shownin Figure A.20.

You should now see a success message, as shown in Figure A.21. If error messages arereturned, check that the credentials you used to connect to the TESTDB database are correct, andthat you have set the appropriate environment variables correctly.

Page 496: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Configuring a JDBC Resource 459

Figure A.20 Testing the connection to the TESTDB data source.

Figure A.21 Successful test of the TESTDB data source.

NOTE

Before the TESTDB becomes available in WPF, you need to restart the application server.

You have now configured a JDBC data source for the contacts database, and you are readyto start building the example in Chapter 3.

Page 497: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 498: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

461

A P P E N D I X B

Portlet FactoryProperties

This appendix lists and describes the properties files included with WebSphere Portlet Factory(WPF) and it highlights some of the most important and commonly used settings contained inthem. The following areas are covered in this appendix:

• Properties files

• Using properties

Properties Files

WPF uses a number of text-based properties files, which contain settings that alter the way yourapplication behaves. In most cases, you don’t need to change these files, as the default settings aresufficient. However, changing these files can help you fine tune and tweak your applications, so itis a good idea to spend time familiarizing yourself with some of the more important settings. Youcan find these files in the WebContent/WEB-INF/config directory of any WPF project (storedwith the extension .properties).

TIP

Although you can change any of the properties files directly, you should always make yourchanges in an override.properties file and leave the original files intact. Any settings in anoverride.properties file will override those in other properties files, and keeping all of yourchanges in one place will enable you to easily see what you have changed (and revert backto the default settings if necessary). Also, using an override.properties file will prevent yoursettings from being overwritten by new installs or upgrades of WPF.

Page 499: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Although there are other files in the config directory used to configure your project (such asthe selection handler configuration files that are discussed in Chapter 12, “Profiling Portlets”),only files with a .properties extension are considered properties files. Properties contained inproperties files are the only settings that can be overwritten using an override.properties file.

The following sections list the properties files used in WPF and provide brief descriptionsof how each file is used.

bowstreet.properties, cluster.properties, and server.properties

These files store general settings for your WPF application and contain the majority of the prop-erties used in WPF. These are the properties files you are most likely to change when configuringyour WPF application.

For example, the bowstreet.properties file contains project directory and file locations, andthe cluster.properties file stores settings for file uploads and Simple Object Access Protocol(SOAP). The server.properties file contains properties that specify hostnames and port numbers(this is particularly useful if you want to configure WPF to run through a proxy).

jdbcDrivers.properties, pageprocessors.properties,

persistentstore.properties

These files store settings for the Java Database Connectivity (JDBC) drivers used in WPF. Youshould leave these files with their default values, as they do not contain any documented settingsthat can be modified. Note that the data source settings in these files are independent from thedata source settings found in builder calls (you should use the builder settings wherever possible).

log4j.properties

This file stores advanced settings pertaining specifically to the log4j logging capabilities of WPF.You do not normally need to change this file, but doing so enables you to set such things as logfile truncation thresholds and logging categories.

logging.properties

This file contains several high-level settings for logging in WPF, mainly for logging server statis-tics and enabling or disabling particular logging filters.

migrate-profilesets.properties

This file contains settings for migrating your properties files into a relational data store, such as Ora-cle, SQL Server, or DB2. Normally you migrate only your profile sets if you want to enable users toedit profile values at runtime, but do not want to make the Edit or Configure modes available.

In addition to these files, projects with the Lotus Collaboration Extension feature set alsohave a domino_config directory under the config directory, which you should use to store yourDomino server connection properties files (similar directories are also created when you use any

462 Appendix B Portlet Factory Properties

Page 500: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

of the other Integration Extension feature sets, such as the SAP Extension). By default, WPF cre-ates a file called default_domino_server.properties in this directory, which you need to configureto point to your Domino server for any of the Domino builders to work correctly. You can makecopies of this file to store settings for different servers, and a single project can contain as manyconfiguration files as there are Domino servers in your environment. Setting up WPF to connectto Domino is discussed in the “Configuring Lotus Domino” section of Appendix A.

Changes to properties files normally take effect instantly; however, certain settings requirethe server where the application is deployed to be restarted. These settings are listed in Table B.1.

Table B.1 Properties That Require a Server Restart

Properties File Property

bowstreet.properties bowstreet.location.packaging

bowstreet.cache.model.size

bowstreet.cache.builderInfoCheckInterval

bowstreet.cache.builderRegenLoadInterval

bowstreet.cache.model.timeOutMinutes

bowstreet.logging.log4j.configFile

bowstreet.logging.log4j.watchInterval

bowstreet.location.models.path

bowstreet.location.models.dumpInfoLevel

bowstreet.settings.RequestMemThreshold

bowstreet.settings.stringObscureHandler

bowstreet.cache.output.disable

bowstreet.settings.sourcemodelmanager.modelprocessinginterval

cluster.properties server.domain

bowstreet.engine.uniqueIDPrefix

bowstreet.settings.userDataStorageHandler

bowstreet.upload.enabled

bowstreet.upload.destinationPath

bowstreet.upload.maxFileSizeK

bowstreet.session.semaphore.timeOut

Properties Files 463

(continued)

Page 501: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table B.1 Properties That Require a Server Restart (continued)

Properties File Property

bowstreet.profiles.cache.waitTime

bowstreet.soap.enabled

bowstreet.soap.targetModelURIPrefix

bowstreet.soap.requestURLPathInfo

bowstreet.session.cookieless.enabled

bowstreet.session.cookieless.parameter

persistentstore.properties persistentstore.hashtable.capacity

persistentstore.hashtable.loadfactor

persistentstore.storage.type

persistentstore.defaultrecord.binaryortext

persistentstore.defaultrecord.isref

persistentstore.defaultrecord.saveunique

persistentstore.defaultrecord.version

server.properties server.htmlRoot

server.http.port

server.https.port

server.service.directory.checkTimestamp

server.service.directory

java.protocol.handler.pkgs

Using Properties

This section lists some of the more useful functions you can perform by modifying properties inthe WPF properties files. Remember that you should not modify any of the default properties filesdirectly, but use an override.properties file instead (stored in the WebContent/WEB-INF/configdirectory or in the plugins/com.bowstreet.designer.core[version]/config directory if you want theproperties to be overridden only when your application is run from WPF Designer).

The following functions are covered in this section:

• Domino server settings

• File upload settings

464 Appendix B Portlet Factory Properties

Page 502: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

• Specification of an alternate compiler

• Dynamic class loading

• SOAP and proxy access for Web services

• Errors caused by file length limitations

• The WPF cache

• General logging

• Debug tracing

• Event logging

• Page automation

TIP

An override file doesn’t exist by default, so if you want to change any properties, you shouldcreate a file called override.properties in the WebContent/WEB-INF/config directory.Another copy of the override file is used in WPF; it is stored by default in theplugins/com.bowstreet.designer.core[version]/config directory where WPF was installed(where [version] is the version of your WPF installation). This file overrides properties onlywhen your application is run from the WPF Designer.You can specify an alternative to thissecond override file for all the projects in your current workspace by selecting Window,Preferences, and then by changing the Override Properties File Location setting under theWebSphere Portlet Factory Designer heading.

Domino Server Settings

If you want to connect to a Domino server from WPF, you need to modify the properties shown inTable B.2, which can be found in the default_domino_server.properties file. By default, this file islinked to from builder calls that require Domino connectivity; alternatively, you can use a differ-ent file, as long as you change the Properties file input in the relevant builder calls. The directorythat contains the default_domino_server.properties file, WebContent/WEB-INF/config/domino_config, exists only when your project has the Lotus Collaboration Extension feature set added.

The ServerName property specifies the hostname for the Domino server you want to con-nect to. Note that the port number must be included if you are not connecting to Domino via port80 (WPF uses DIIOP on port 63148 to connect to Domino by default). The Username and Pass-word properties specify the credentials of a Domino user with access to browse databases on theDomino server.

Using Properties 465

Page 503: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table B.2 Configuring Domino Server Settings

Properties File Property Example Setting

default_domino_server.properties ServerName domino.local.com:63148

Username dominoAdmin

Password password

File Upload Settings

Before you can use the File Upload builder in WPF, you need to enable file uploading by settingthe bowstreet.upload.enabled property to true. The bowstreet.upload.destinationPath propertydefines the path used to store uploaded files, and the bowstreet.upload.maxFileSizeK propertydefines the maximum file upload size in Kb. Finally, the bowstreet.session.semaphore.timeOutproperty defines a time limit (in seconds) that is used for file upload requests.

The settings used to configure file uploading are shown in Table B.3.

Table B.3 Configuring File Upload Settings

Properties File Property Example Setting

cluster.properties bowstreet.upload.enabled True

bowstreet.upload.destinationPath ${bowstreet.rootDirectory}/upload

bowstreet.upload.maxFileSizeK 500

bowstreet.session.semaphore.timeOut 45

Specifying an Alternate Compiler

If you have multiple JDKs available to you, you can specify an alternate compiler for your Javacode and JSPs by setting the property shown in Table B.4. This can be useful when you want touse features from a particular JDK version.

Table B.4 Specifying an Alternate Compiler

Properties File Property Example Setting

cluster.properties bowstreet.methods.compiler C:/jdk131/bin/javac.exe

Dynamic Class Loading

In WPF, it is possible to dynamically load classes that aren’t on your classpath. Dynamicallyloaded classes can be reloaded without needing to restart your application, which can help speed

466 Appendix B Portlet Factory Properties

Page 504: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

up the development process. Note that dynamic class loading with a large number of classes canaffect the performance of the application itself, but this effect is usually negligible. As a best prac-tice, however, it is recommended that you only enable dynamic class reloading in developmentenvironments, and disable it when deploying into production.

The settings used to configure dynamic class loading are shown in Table B.5. The bow-street.dynamic.class.load.checkTimestamp property specifies whether dynamic class loading isenabled. A value of false disables dynamic class loading; a value of true causes a timestampcheck to be performed whenever a Java class or JSP is accessed. This check then determineswhether the resource needs to be reloaded. The bowstreet.dynamic.class.load.path propertydetermines the directories (separated by commas) from which Java classes are dynamicallyloaded.

Table B.5 Configuring Dynamic Class Loading

Properties File Property Example Setting

bowstreet.properties bowstreet.dynamic.class.load. truecheckTimestamp

bowstreet.dynamic.class. ${bowstreet.rootDirectory}/work/classes,load.path ${bowstreet.rootDirectory}/work/lib

SOAP and Proxy Access for Web Services

The properties in the bowstreet.properties file shown in Table B.6 enable you to specify settings(hostname, port, username, and password) for a proxy server to use when retrieving WSDLs orrequesting access to Web services. Proxy settings can also be configured under the Advanced sec-tion of the Web Service Call builder.

The cluster.properties settings shown in Table B.6 are for configuring the use of SimpleObject Access Protocol (SOAP) in WPF, which is used to communicate with Web services. Thebowstreet.soap.enabled property specifies whether SOAP messages are used when communicat-ing with Web services (disabling this property renders the values of the other properties redun-dant). The bowstreet.soap.wsdl.fetchTimeout property specifies the default timeout (in seconds)on the fetch WSDL operation performed from the Web Service Call builder. The bowstreet.soap.targetModelURIPrefix property specifies a default targetNamespace for WSDLs generated fromyour model, and the bowstreet.soap.httpErrors property specifies whether to send HTTP Errors aspart of the SOAP fault envelope (SOAP fault envelopes are part of the response sent back from acalled Web service).

Using Properties 467

Page 505: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

468 Appendix B Portlet Factory Properties

Table B.6 Configuring SOAP and Proxy Access for Web Services

Properties File PropertyExample Setting

server.properties bowstreet.soap.proxyHost= melbourne.local.com

bowstreet.soap.proxyPort= 6789

bowstreet.soap.proxyUser= proxyUser

bowstreet.soap.proxyPassword= password

cluster.properties bowstreet.soap.enabled true

bowstreet.soap.wsdl.fetchTimeout 60

bowstreet.soap.targetModelURIPrefix http://wpf.ibm.com/2002/03/models/

bowstreet.soap.httpErrors true

Avoiding Errors Caused by File Length Limitations

Some application servers have a limit of 255 characters on the length of application path names.If you experience problems caused by the path name of your application being too long, you canchange the property in Table B.7 so that WPF generates the profile name portion of your pathname (not the entire path name) as a relatively compact and uniquely identifying string (providedit exceeds the value of the bowstreet.profiles.maxKeyLength property). Note that using shortermodel and action names can also help to circumvent errors caused by file length limitations.

Table B.7 Avoiding Errors Caused by File Length Limitations

Properties File Property Example Setting

cluster.properties bowstreet.profiles.maxKeyLength 60

TheWPFCache

WebApps, models and the output of certain actions can all be cached in WPF, and this cache canbe configured using the properties in Table B.8. The bowstreet.cache.output.disable propertyenables or disables the caching of output from your application (you can cache actions in yourapplication using the Cache Control builder). The bowstreet.cache.model.size property sets thetotal number of models and WebApps you can have in the cache at any one time. When changingthis setting for an application that uses profiling, keep in mind that you may have multipleWebApps for a single model. Finally, the bowstreet.cache.model.timeOutMinutes property spec-ifies how many minutes the unused models will stay in the cache before they are discarded.

Page 506: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table B.8 Configuring the WPF Cache

Properties File Property Example Setting

bowstreet.properties bowstreet.cache.output.disable false

bowstreet.cache.model.size 30

bowstreet.cache.model.timeOutMinutes 20

log4j Logging

Many of the logging properties in WPF define log4j logging categories and utilize the log4j for-mat. The first value of a logging category property is the priority level, which defines the level ofinformation to be returned for that category. In order of restrictiveness, these priority levels areDEBUG, INFO, WARN, ERROR, and FATAL, with DEBUG being the most inclusive logginglevel and FATAL being the most restrictive. The other values in a logging category propertydefine appenders and layouts. An appender declares an output destination for logging informa-tion (such as Console), and a layout determines how the information should be presented (such asModelActions). Note that custom logging categories can also be specified using the Logging Cat-egory builder.

Table B.9 shows some of the properties used for configuring log4j logging in WPF. Thelog4j.rootCategory property is a log4j category property that defines the default priority level,appenders, and layouts for WPF logging. The log4j.logger.bowstreet.system.out property definesthe log4j category for System.out calls made from the Action List builder.

TIP

You can make System.out calls from the Action List builder by selecting Special/SystemOutfrom the Select Action dialog, which you open by pressing the Ellipsis button next to anaction in the Action List builder.

The remaining properties in Table B.9 define logging levels for several useful areas ofWPF. Many of these categories have a default value of WARN, which means that no output isgenerated, so you need to increase these levels to get logging output. For more information onthese properties, see the WPF Help under Reference, Property Files, Log4j properties.

Using Properties 469

Page 507: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table B.9 Configuring General Logging

Properties File Property Example Setting

log4j.properties log4j.rootCategory WARN,Console,General

log4j.logger.bowstreet.system.out INFO,Console

log4j.logger.bowstreet.profile.selectionHandler INFO,ProfileSelectionHandler

log4j.logger.bowstreet.system.request WARN,Request

log4j.logger.bowstreet.system.profileSelection WARN,ProfileSelection

log4j.logger.bowstreet.system.regen WARN,Regen

log4j.logger.bowstreet.system.builderCalls WARN,BuilderCalls

log4j.logger.bowstreet.system.modelActions WARN,ModelActions

log4j.logger.bowstreet.system.webservice. WARN,ServiceCallsserviceCall

log4j.logger.bowstreet.system.webservice. WARN,IncomingSOAPincomingSOAPRequest Requests

log4j.logger.bowstreet.builders.webapp. WARN,ServiceConsumerserviceConsumer

Debug Tracing

Debug tracing enables you to automatically log information about different parts of your applica-tion, and it is enabled by adding the Debug Tracing builder to a model in your project. Debugtracing information is written to the debugTracing.txt file in the WebContent/WEB-INF/logsdirectory, the application server’s console window and also to the System.out file on the applica-tion server. See Chapter 14, “Error Handling, Logging, and Debugging,” for more information onlogging and debug tracing in WPF.

It is recommended that you set the default debug tracing information level to DEBUG toreceive more detailed information. You can do this by setting the property shown in TableB.10 toDEBUG,Console,DebugTracing.

Table B.10 Configuring Debug Tracing

Properties File Property Example Setting

log4j.properties bowstreet. system.debugTracing DEBUG,Console,DebugTracing

470 Appendix B Portlet Factory Properties

Page 508: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Event Logging

An event in WPF logging refers to when a logging message is generated. Table B.11 shows someof the properties you can use to configure event logging.

The logging.driver.eventSink.directory property declares the location of your event logfiles (relative to the WPF installation directory). Changes to this property do not take effect untilyou restart the application. The logging.driver.eventSink.prefix property defines the prefix forevent log files, and the logging.driver.eventSink.suffix property defines the suffix (event log fileshave the format: prefix + timestamp + suffix). The logging.driver.eventSink.maxSize propertydefines the maximum size (in Kb) of your event log files—if a file exceeds this limit, it no longerhas to be written to and a new file is created. The logging.event.flush.interval property defines thetime interval (in seconds) that WPF waits before writing messages to the log file. You can also usethe logging.event.criterion.abnormal.flushImmediately property to define when logging mes-sages are written to the log file, which overrides the logging.event.flush.interval property.

Table B.11 Configuring Event Logging

Properties File Property Example Setting

logging.properties logging.driver.eventSink.directory ${bowstreet.rootDirectory}/logs

logging.driver.eventSink.prefix event_

logging.driver.eventSink.suffix .log

logging.driver.eventSink.maxSize 1000

logging.event.flush.interval 60

logging.event.criterion.abnormal. trueflushImmediately

Server Statistics Logging

A number of server statistics can be logged in WPF, which are configured via the logging.proper-ties file. Table B.12 shows some of the properties you can use to configure server statisticslogging.

The logging.serverStats.enabled property determines whether server statistic logging isenabled, and the logging.serverStats.snapshotInterval property specifies an interval (in seconds)to poll a server for statistics. The log4j.additivity.bowstreet.system.server.logging.serverStatsproperty denotes whether server stats are written only to the server stats file and not to the Sys-tem.out log. The log4j.logger.bowstreet.system.server.logging.serverStats property specifies alogging level for server stats (INFO is the recommended level).

Server statistics are discussed in more detail in Chapter 14 of this book.

Using Properties 471

Page 509: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table B.12 Configuring Server Statistics Logging

Properties File Property Example Setting

logging.properties logging.serverStats.enabled true

logging.serverStats.snapshotInterval 300

log4j.additivity.bowstreet.system.server.logging.serverStats false

log4j.logger.bowstreet.system.server.logging.serverStats INFO,ServerStats

Page Automation

The automation of constructing Web page interfaces (and how information in these interfaces isformatted and stored) is a major feature of WPF, and a number of builders are available (such asthe Data Page builder and Data Field Modifier) to configure this process. There are also a numberof properties that can be used to configure page automation, which are shown in Table B.13.

The first six properties in Table B.13 define the way the Date, Time, and DateTime datatypes are stored and displayed. The bowstreet.pageautomation.date.data property defines the wayDate datatypes are stored, and the bowstreet.pageautomation.date.display property defines theway they are displayed. The bowstreet.pageautomation.dateTime.data property defines the wayDateTime data types are stored, and the bowstreet.pageautomation.time.data property defines theway they are displayed. Finally, the bowstreet.pageautomation.time.data property defines theway Time datatypes are stored, and the bowstreet.pageautomation.time.display property definesthe way they are displayed.

The bowstreet.pageautomation.date.yearAdjustCutoff property is used to parse dates fordifferent centuries, primarily when two-digit year values have been specified. Any year valuesless than the value of this property have 2000 added to them (it is assumed that the date is in thetwenty-first century); year values that are greater than the value of this property have 1900 addedto them (it is assumed that the date is in the twentieth century). This property should be com-mented out when working with dates prior to the twentieth century.

Finally, the bowstreet.pageautomation.force_separate_leaf_when_repeated property isused to specify whether repeated elements in XML variables should be displayed separately (avalue of true) or separated with commas (a value of false).

472 Appendix B Portlet Factory Properties

Page 510: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Table B.13 Configuring Page Automation

Properties File Property Example Setting

bowstreet.properties bowstreet.pageautomation.date.data MM/dd/yyyy

bowstreet.pageautomation.date.display MM/dd

bowstreet.pageautomation.dateTime.data MM/dd/yyyy hh:mm:ss

bowstreet.pageautomation.dateTime.display MM/dd hh:mm

bowstreet.pageautomation.time.data hh:mm:ss

bowstreet.pageautomation.time.display hh:mm

bowstreet.pageautomation.date.yearAdjustCutoff 50

bowstreet.pageautomation.force_separate_leaf_ falsewhen_repeated

Using Properties 473

Page 511: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 512: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

475

Glossary

This glossary provides brief definitions of the main technical terms used in this book.

Action

A command that can be run from a buildercall. There are a number of actions availableby default (such as Assignment and SystemOut) but actions can also be defined usingbuilder calls (such as Method, Web ServiceCall, Action List, or Page builder calls).Actions are called from builder inputs—forexample, the Button builder has an Actionbuilder input that lets you specify the actionthat is run when the button is clicked.

Ajax

See Asynchronous JavaScript and XML.

Ant script

An XML file often used to automate theprocess of building Java projects. Requires theAnt software library from Apache, which is anopen source library that is freely availablefrom the Apache website (http://ant.apache.org).

API

See Application Programming Interface.

Appender

An entry in a log4j property that defines anoutput destination for logging information.

Applet

A small program that is run on a client (suchas a Web browser), as opposed to running on aserver (as a servlet does), that can be run fromWPF applications via the Applet builder.

Application

In the context of WPF, an application is a setof deployable files (stored in a WAR file) thatcan be run on an application server or portalserver. There are two types of WPF applica-tions: a portal application, which can containone or more portlets that are hosted on a portalserver and accessed through a portal, or a Webapplication, which is hosted on an applicationserver and is accessed without having to gothrough a portal.

Page 513: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Application Programming Interface (API)

A code-based interface for accessing a com-puter program’s functionality. For example,portlets built to the JSR-168 standard utilize aparticular collection of methods and classes(the JSR-168 portlet API) on the backend,which provides access to certain functionality(such as accessing user configuration optionsfor the portlet).

Application server

A server (such as WebSphere ApplicationServer) that runs applications (such as thosestored in EAR or WAR files) and serves up theresults to a client (such as a Web browser).Application servers often have features formanaging the various parts of an application,such as security and data access.

Application server deploymentconfiguration

A collection of settings for deploying one ormore applications to a target applicationserver. Note that either an ordinary applica-tion server or a portal server can be specifiedas a target in an application server deploymentconfiguration. See also portal server deploy-ment configuration and deployment configu-ration.

Applied Profiles view

In the WebSphere Portlet Factory perspective,this view enables you to test the effects of pro-files on your application from within the WPFDesigner.

Asynchronous JavaScript and XML (Ajax)

A technology that lets you update a Web pagewithout having to reload the entire page. Ajaxworks by making JavaScript calls that com-municate via XML data. The Ajax Region and

Ajax Type-Ahead builder both let you workAjax functionality into your WPF applica-tions.

Attribute

Provides information about a tag or element ina markup language, such as HTML or XML.For example, the name attribute in this HTMLfragment provides the name of the <span>tag:

<span name=”navigation”>

See also element.

BAT file

See batch file.

Batch file

A file with a .bat extension that runs asequence of commands when executed. Sev-eral useful batch files are provided with WPFin the WebContent/WEB-INF/bin directory inyour project.

BDEF

The file extension for a builder definition. Seebuilder definition.

Breadcrumbs

In the context of a portal, breadcrumbs are astyle of navigation that gives users an indica-tion of their current page location in the portalhierarchy.

Browser

See Web browser.

Build

Building a project can refer to one of twothings. First, it can refer to the process of com-piling project code (performed automaticallywhen you save changes to a Java source file or

476 Glossary

Page 514: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

when you use the Build commands under theProject menu in the WPF Designer). Theproduct of this process is sometimes referredto as a build. Second, it can refer to theprocess of creating deployable WAR files(performed via the WPF menu options in theproject context menu). These WAR files canthen be deployed to an application server orportal server.

Build path

See Java build path.

Builder

A WPF artifact that has a wizard-like interfaceand that helps automate the developmentprocess. They can do anything from put a but-ton on a form, to load a Web page, or to accessa Web service. WPF comes with over 160builders, and you can also create your ownbuilders to automate common developmenttasks.

Builder call

An entry in a model that invokes a particularbuilder. Double-clicking a builder call in yourIDE opens the builder’s interface in theBuilder Call Editor.

Builder definition

A .bdef file that defines how to invoke abuilder and how to display it when a developerwants to use it. You don’t normally need toworry about .bdef files unless you create yourown builders.

Builder input

A field on a builder that enables developers toconfigure the builder’s settings, such as thenumber of rows to place on a page or the labelfor a button. Builder inputs can be profiled;

that is, the value of the input can be deter-mined by a profile.

Builder palette

A dialog box used to add builder calls to amodel; it can be accessed via the Cog icon inthe Outline view.

Business logic

The rules governing an application that reflectthe way the business is run. In WPF, businesslogic is usually implemented in action lists orin Java code. Code that handles workflow isan example of business logic.

Cascading Style Sheet (CSS)

A file with a .css extension that defines pres-entation styles for a document written in amarkup language (such as HTML). Cascadingstyle sheets can be referenced from the StyleSheet builder, through builder inputs, ordirectly from an HTML page.

Category

See logging category.

Classpath

Tells the JVM where to look for user-definedclasses and packages. The classpath is nor-mally defined in an environment variablecalled CLASSPATH.

Configuration file

See properties file.

Construct

An abstract type that WPF matches to certainHTML fragments. It contains one or more ele-ments (or even other constructs) that definehow HTML should be laid out and formatted.Constructs are specified in HTML templates.

Glossary 477

Page 515: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Consumer

See service consumer.

Controller

Refers to the part of an application thathandles execution flow and responds toevents. A controller is usually employed aspart of a Model View Controller pattern. InWPF, the Factory controller servlet acts as acontroller, routing off requests to your appli-cation.

Criterion

See logging criterion.

CSS

The file extension of a cascading style sheet.See Cascading Style Sheet.

Data set

A collection of data. Data sets are usually pre-sented to users in WPF applications using theData Page builder.

Data source

A repository for storing data, which WPF con-nects to and then processes in some way (usu-ally by displaying the data on the screen in aneasy to understand format). A data sourcecould be anything from a complex database toa simple text file. You would normally connectto a data source in WPF using a serviceprovider, or from an application server via aJDBC data source.

Deploy

In the context of WPF, refers to the process ofupdating a WAR file on an application serveror portal server. In WPF, you can automati-cally deploy your applications (unless they arelocated on a remote machine and are notaccessible through a mapped drive).

Deployment configuration

A collection of settings for deploying one ormore applications to a target applicationserver or portal server. See also applicationserver deployment configuration and portalserver deployment configuration.

Deployment WAR file

See Factory deployment WAR.

Designer

See WebSphere Portlet Factory Designer.

Detail

In WPF, an individual record in a result setreturned from a data source. A collection ofrecords is referred to as a list.

Development WAR file

See Factory development WAR.

DIIOP

See Domino Internet Inter-Orb Protocol.

Document (Lotus Notes)

Databases in Lotus Notes are made up of doc-uments. A document is the rough equivalentof a record in a relational database and con-sists of a series of fields, which hold valuesthat describe different attributes of the docu-ment. Documents are usually created using aform.

Document (XML)

See XML document.

Dojo

An open source JavaScript toolkit that facili-tate dynamic functionality in Web applica-tions.

478 Glossary

Page 516: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Domino Internet Inter-Orb Protocol(DIIOP)

By default, WPF uses DIIOP to connect toDomino. In order to establish this communi-cation link, the DIIOP task must be started onthe Domino server. Alternatively, you can alsoconfigure WPF to communicate with Dominovia HTTP.

Domino server

The main functions of a Domino server (oftenjust referred to as Domino) are to serve upLotus Notes databases and to run the variousprocesses required to access and managethese databases.

EAR

See Enterprise Archive.

Eclipse

A Java-based IDE that can be used to buildJ2EE applications. A number of other IDEsare based on Eclipse, such as Rational Soft-ware Developer and Rational Software Archi-tect. WPF installs into a variety ofEclipse-based IDEs. For a full list of IDEssupported by the version of WPF you areusing, consult the WPF Release Notes.

Editor

A screen in an Eclipse-based IDE that lets youinput information. You can save informationin an editor, something you would not nor-mally do from a view. The Model Editor andProfile Set Editor are the main editors used inWPF, although editors for plain text and XMLdocuments are also often used.

EJB

See Enterprise Java Bean.

Element

In the context of a markup language, a partic-ular section of structured content denoted by astart tag and an end tag. For example, thisHTML fragment defines a span element,bounded by a start tag and an end tag:

<span name=”navigation”></span>

Elements are organized hierarchically; forexample, an HTML element often encom-passes a body element, which will usually, inturn, encompass other elements. See alsoattribute.

Enterprise Archive (EAR)

A file used to package several modules (suchas WAR files) together. It is deployed and exe-cuted on an application server. When adeployment WAR is created, it is stored insidean EAR file. EAR files can be viewed usingmost compression utilities.

Enterprise Java Bean (EJB)

A server-side component used in many J2EEapplications, usually for the purpose of han-dling business logic.

Event (logging)

See logging event.

Event (portal)

A trigger method in a portlet used to passproperties and notifications between portlets.In WebSphere Portal, an entity called the Web-Sphere Property Broker is often used tohandle these events.

Execution time

Refers to when the JSPs in an application areexecuted on a server.

Glossary 479

Page 517: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Extensible Markup Language (XML)

A markup language used to hierarchicallystructure data. XML data is stored in an XMLdocument, and these documents are usedextensively in WPF (especially for communi-cation between services). The structure ofXML documents is normally defined by anXML schema.

Factory

Although the word factory is sometimes usedto describe a method or class whose purposeis to create other objects, it is also used asshorthand in the context of WPF developmentto refer to WebSphere Portlet Factory itself.

Factory controller servlet

The Factory controller servlet (WebEngine-Servlet) handles requests to your applicationat runtime. All model requests must passthrough the Factory controller before theyreach any given model.

Factory Deployment WAR

An application created in WPF, normallydeployed to a WebSphere Application Server.Deployment WARs are generally used todeploy non-portlet applications into produc-tion environments. Deployment options for theFactory Deployment WAR are specified in theapplication-server deployment configuration.

Factory Development WAR

A development version of a WPF applicationthat contains useful design artifacts in devel-opment that you normally wouldn’t want todeploy to a production environment. FactoryDevelopment WARs must be deployed to anapplication server. Deployment options forthe Factory Development WAR are specifiedin the application server deployment configu-ration.

Factory generation engine

The WPF mechanism used to generateWebApps from builder calls in a model. Seealso Generation time.

Field

A space on a form for a piece of informationthat can be modified by the user or by code onthe form.

Form

Used to enter data into a computer system andconsists of one or more fields. In HTML,forms are specified with the <form> tag. InLotus Notes databases, forms are design arti-facts that can be accessed with a LotusDesigner client.

Formatter class

In WPF is a Java class that can be used to for-mat, translate, or validate fields in a Webapplication (such as a portlet). Formatterclasses implement the com.bowstreet.meth-ods.IInputFieldFormatter interface.

Generation

Refers to the process of creating WebAppsfrom model and profile combinations.

Generation class

Specifies logic for a builder to carry out togenerate code for a WebApp.

Generation time

Refers to when a WebApp is generated. AWebApp is generated from the IDE eitherwhen a model is opened, a builder call issaved, or changes to a model or builder callare applied. A WebApp can also be generatedfrom the server that the application isdeployed to when a request to the applicationrequires that a particular profile and model

480 Glossary

Page 518: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

combination are used for the first time. A gen-eration class is used to declare what actions abuilder should perform during generationtime.

HTML

See Hypertext Markup Language.

HTML template

An HTML file used to specify the structureand formatting of WPF output.

HTTP

See Hypertext Transfer Protocol.

HTTP Session

An object that enables developers to identifyinformation about users as they progressthrough a Web application. HTTP Sessionsare often used in WPF—for example, sessioncan be specified as the scope of a shared vari-able in the Shared Variable builder.

Hypertext Markup Language (HTML)

A markup language used to author Web pages.HTML consists of plain text and a number oftags that describe the text.

Hypertext Transfer Protocol (HTTP)

A communication protocol used for ordinaryWeb browsing.

IDE

See Integrated Development Environment.

Integrated Development Environment(IDE)

Software that combines several programmingtools (such as editors, compilers, and so on)into one package, enabling developers to use a

single environment to perform multiple tasksin the development lifecycle.

IXml

A WPF interface used for manipulating XMLdocuments.

J2EE

See Java 2 Enterprise Edition.

JAR

See Java Archive.

Java

A programming language based on the ideathat the same code should be executable onmultiple devices. Compiled Java code is runfrom a Java Virtual Machine, which convertsthe code into a format that the underlyingoperating system can understand, and thenexecutes it.

Java 2 Enterprise Edition (J2EE)

A powerful Java framework used to buildserver-side applications to work across organ-izations and groups of people. J2EE applica-tions are usually tiered to some degree (usingthe MVC pattern, for example) and can bebuilt using WPF.

Java Archive (JAR)

A .jar file that contains a collection of com-piled Java files. JARs are normally used to dis-tribute Java classes, and importing a JAR fileinto a project gives you access to the function-ality of the JAR from within the project. Thecontents of a JAR file can be viewed usingmost compression utilities.

Glossary 481

Page 519: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Java Bean

A dynamic, reusable component in Java thatconforms to certain conventions (for example,it utilizes get and set methods for its proper-ties).

Java build path

In WPF, this is the file path used to find otherclasses accessed in your code; it can beaccessed from the Project Properties dialog.

Java Database Connectivity (JDBC)

An API used to connect to a database from aJava program. In WPF, it is possible to con-nect to JDBC-compliant databases withoutknowing the details of the JDBC API, as sev-eral of the data connectivity builders haveinbuilt support for JDBC.

Java Development Kit (JDK)

Sun software that enables you to create, com-pile, debug, and run Java applications. WPFDesigner uses a JDK on the backend to facili-tate its Java-related features.

Java Message Service (JMS)

A set of Java APIs for creating, reading, send-ing, and receiving messages (which is com-prised of a header, a body, and properties) inJ2EE applications.

Java Naming and Directory Interface(JNDI)

An interface for accessing naming and direc-tory services.

Java Runtime Environment

A software package (available for free online)that enables a computer to run Java applica-tions.

Java Server Page (JSP)

A language used to write Web pages. JSPs aresimilar to HTML, the main difference beingthat they can also contain Java code.

Java Virtual Machine (JVM)

Converts Java class files into machine lan-guage and then executes it. This enables thesame Java code to be executed on multipledevices and operating systems.

JavaScript

This scripting language can be embedded inWeb pages. As in other development environ-ments, JavaScript should be used with cautionin WPF, as some clients do not support it.

JDBC

See Java Database Connectivity.

JDBC data source

A collection of settings on an applicationserver used to connect to a data source usingthe JDBC API.

JDK

See Java Development Kit.

JMS

See Java Message Service.

JNDI

See Java Naming and Directory Interface.

JRE

See Java Runtime Environment.

JS

See JavaScript.

482 Glossary

Page 520: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

JSP

See Java Server Page.

JSR-168

A set of standard Java APIs for buildingportlets.

JVM

See Java Virtual Machine.

Layout

An entry in a log4j property that defines howlogging information should be laid out.

LDAP

See Lightweight Directory Access Protocol.

LDAP Directory

A hierarchically structured directory of infor-mation. An LDAP directory is served up toclients via an LDAP server.

LDAP Server

Serves up an LDAP directory to clients.

Lightweight Directory Access Protocol(LDAP)

A communication protocol used between anLDAP server and an LDAP client.

Linked Java Object (LJO)

A builder that links to a Java class file. After itis linked, an LJO can be accessed directlyfrom within your model, which means that themethods of the linked class become accessiblefrom builder calls capable of executingactions.

List

A collection of records in a result set returnedfrom a data source is referred to in WPF as alist. Individual records are referred to as thedetail.

LJO

See Linked Java Object.

log4j

A collection of Java classes used for logginginformation about applications. log4j is theprincipal logging mechanism used in WPF.

Logging category

Used to define how and where logging infor-mation is stored in log4j. The default loggingcategories are DEBUG, INFO, WARN,ERROR, and FATAL. You can create yourown logging categories using the LoggingCategory builder.

Logging criterion

A set of conditions applied to a logging cate-gory, which defines the logged events for thatcategory based on configured attributes or fil-ters. See also logging event.

Logging event

Occurs when a message is triggered to belogged. Whether the event is logged dependson the configured logging categories and anylogging criteria specified.

Lotus Notes

A software tool typically used to facilitate col-laboration in an organization. Lotus Notesfunctionality has traditionally been providedvia non-relational databases, although ver-sions 7 and later of Lotus Notes can be used tostore information in a relational format aswell.

Markup language

Used to write text and information thatdescribes or structures that text. For example,HTML can be used to structure a Web page,and XML can be used to structure data.

Glossary 483

Page 521: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Metadata

Data that describes other data. A Rich DataDefinition, for example, is metadata thatdescribes how a particular data set should bedisplayed.

Model (pattern)

In the context of the MVC design pattern, amodel refers to the data and business logic inan application. See also Model View Con-troller pattern.

Model (WPF design artifact)

A collection of builder calls used to assemblea WPF application. Models are edited usingthe Model Editor in the WPF Designer, andthey are persisted as XML on the backend.

Model Editor

An interface component used for editingbuilder calls in a model; it appears in the top-right quadrant of your IDE (when using theWPF perspective).

Model View Controller (MVC) pattern

A commonly used design pattern used to sim-plify large applications and make them easierto maintain. The pattern consists of three tiersthat correspond to different parts of the appli-cation architecture: a model for data and busi-ness logic; a view for presentation components(such as JSPs and images); and a controller forexecution flow and for responding to events.

Model XML

This tab displays in the editor section of yourIDE when you have a model open, and showsthe XML persisted to disk for the currentlyactive model in the IDE.

MVC

See Model View Controller pattern.

Namespace

A uniquely identifying context for the itemscontained within it. See also XML Name-space.

Non-relational database

A database that is not structured around theidea of tables and the relationships betweenthese tables. A Lotus Notes database is anexample of a non-relational database; it cen-ters around the idea of documents.

Notes

See Lotus Notes.

Open source

Used to describe source code that is publiclyavailable (such as the Ant build tool).

Operation

A method or function in a service is usuallyreferred to as an operation. Operations can bespecified in WPF using the Service Operationbuilder.

Outline view

In the WPF perspective, the Outline view dis-plays the builder calls contained in the cur-rently active model. Double-clicking a buildercall in the Outline view opens the builder’sinterface in the Model Editor. You can alsoadd builders to a model by clicking the Cogicon in the Outline view, which opens thebuilder palette.

484 Glossary

Page 522: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Page

In the context of WPF development, a pageusually refers to a Web page (such as a JSP orHTML page).

Pattern

A commonly used development framework,guideline, or method that facilitates betterapplication development. For example, theMVC pattern is a commonly used pattern inJ2EE development, which makes applicationseasier to maintain.

Perspective

Defines which views and editors are displayedin your IDE, as well as how they are laid out.See also WebSphere Portlet Factory Perspec-tive.

Portal

Provides a flexible framework for aggregating,integrating, and personalizing information inan organization. Users or administrators canadd functionality to portals through portlets,which can then be laid out on a portal page asdesired.

Portal page

A visual container for portlets in a portal.Only one page is viewable at a time. Pages areusually structured in a hierarchy and oftennavigated using menus or breadcrumbs.

Portal server

Provides infrastructure and services to serveup portals to clients (such as Web browsers).WebSphere Portal Server is an example of aportal server.

Portal server deployment configuration

A collection of settings for deploying one ormore applications to a target portal server. Youcannot use an ordinary application server as atarget in a portal server deployment configura-tion—you must use a portal server. See alsoapplication server deployment configurationand deployment configuration.

Portlet

A reusable, loosely coupled presentation com-ponent in a portal. Portlets can be created inWPF by adding a Portlet Adapter builder to amodel containing UI components (portletsrequire a user interface) and an Action Listcalled ‘main’ to display these components. Aportlet is deployed as part of a portlet applica-tion, which can contain many portlets. Afterthey have been deployed to a portal, portletscan be added, moved, personalized, and deletedas desired.

Portlet application

In the context of WPF, a collection of portletsdeployed to a portal server, which combine toproduce a complete application. Portlets in aportlet application may execute independentlyof each other.

Portlet WAR

See WebSphere Portlet WAR.

Primary key

One or more fields that uniquely define arecord in a relational database.

Problems view

In the WPF, perspective lists the design timeerrors in your WPF application, and warnsyou of any possible problems that might occurat runtime.

Glossary 485

Page 523: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Profile

In a WPF application is a collection of valuesused to control how a WebApp is generated. Asingle value in a profile is called a profileentry. A user request for a particular part of anapplication (a certain page for example) canbe associated with a profile based on certaincriteria. After a profile is associated with arequest, the values in the profile are used asinputs to the model-generation process. Thiscan be used to define which page should bedisplayed to the user.

Profile entry

A unit of variability in an application that isused to assign a value to a builder input. Pro-file entries are stored as individual valuesinside a profile. For example, a profile entrycalled mainAction can be used to definewhich action is run when an application starts.The value for the mainAction profileEntry isassigned via a profile, and then it is used as thevalue for a builder input (such as the Actionsinput on the Action List builder).

Profile Set Editor

Usually accessed by double-clicking a profileset. It is used to configure and create profilesets. The Profile Set Editor displays in the top-right quadrant of the screen.

Profile sets

Containers for profiles and profile entries.They also contain configuration settings forthese artifacts. Profile sets are manipulated inthe IDE using the Profile Set Editor, and theyare stored under the WebContent/WEB-INF/profiles directory in files with a .pset exten-sion.

Profiled input

A builder input in which the value of the inputis assigned from a profile entry.

Project

A container in an Eclipse-based IDE for all ofthe design elements in an application. WPFprojects are deployed as WAR files to anapplication server or portal server.

Project Explorer view

One of the main views in the default Web-Sphere Portlet Factory perspective.

Properties file

Contains a collection of settings and their cor-responding values. Properties files in WPF arestored in .properties files in the WebContent/WEB_INF/config directory.

Property

An individual setting used to configure an ele-ment of an application or environment.

Property Broker

See WebSphere Property Broker.

Provider

See service provider.

RAD

See Rational Application Developer.

Rational Application Developer (RAD)

An IDE based on Eclipse and developed byIBM. RAD is a stripped-down version ofRSA, and does not contain any of the addi-tional tools and features for architecting solu-tions found in RSA.

486 Glossary

Page 524: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Rational Software Architect (RSA)

An IDE based on Eclipse and developed byIBM. RSA contains additional tools and fea-tures for architecting solutions not found inRAD.

Rational Web Developer (RWD)

An IDE based on Eclipse and developed byIBM. RWD is a stripped-down version ofRAD that is intended mainly for Web develop-ment.

Record

A single row of a table in a relational data-base. A table of people, for example, mighthave three records—each record describes aparticular person.

Relational database

A database consisting of tables and the rela-tionships between these tables. A SQL data-base is an example of a relational database.

Resource bundle

A collection of properties that define local,specific data. Resource bundles are often usedin WPF to define error messages to display toend users.

Result set

A data set returned from a query, such asthrough a SQL statement or service operation.

Role

This term is used in various contexts in WPFdevelopment to denote an attribute of an entity(such as a user) by which that entity can becategorized. In the context of users, the term‘role’ usually denotes a function that is avail-able to the user. For example, an Editor rolecan be used to categorize certain users as hav-ing access to edit documents.

Root

The top-most entry in a hierarchical structure.

RSA

See Rational Software Architect.

Run

A WPF application is run through a Webbrowser from an application server or portalserver. You can run applications directly fromthe IDE via a run configuration.

Run configuration

Contains a collection of settings that specifyhow you want to preview your applicationsfrom the WPF Designer. The WebSphere Port-let Factory run configuration contains settingsexplicitly dealing with WPF applications.

RWD

See Rational Web Developer.

Schema

See XML schema.

Segment

An individual context (a J2EE role, forexample) that is assigned to a particular pro-file (a Security administrator, for example).Attributes of an individual user request can bemapped to these segments by a selection han-dler, and an appropriate profile is thenemployed.

Selection handler

The mechanism that WPF uses to associateuser requests to your application with particu-lar profiles. Selection handlers are defined inan XML configuration file and a selectionhandling class, which must extend the Selec-tionHandlerBase class.

Glossary 487

Page 525: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Service

An entity (such as a model) that provides oneor more operations, which are then called orconsumed from other models or programs.Services are sometimes made available asWeb services.

Service call

Something that calls an operation on a ser-vice. In WPF, you can call a service by usingthe invoke method of the operation or byusing the execute command of the service.

Service consumer

In WPF, a model that consumes an operationoffered by a service provider. Service con-sumers usually contain a Service Consumerbuilder, but can also consume servicesthrough a Web Service Call builder. See alsoservice provider.

Service Oriented Architecture (SOA)

A software architecture based on a network ofloosely coupled services.

Service provider

Provides one or more operations to be con-sumed as part of a service. A service providercan be defined in WPF using a Service Defini-tion builder and at least one Service Operationbuilder. Alternatively, a Web Service Enablebuilder can be used to convert an existingaction in the model into a Web service. Seealso service consumer and Web service.

Service stub

A model that enables you to provide a serviceto simulate a backend data source, and is par-ticularly useful when connectivity to the back-end is slow or unavailable. Service stubs areused for testing services and are usually cre-ated using the Service Stub builder.

Servlet

A program run on a server, which takes arequest (such as parameters entered by a user)and returns a response (such as HTML).Servlets are deployed and then executed on anapplication server.

Simple Object Access Protocol (SOAP)

A standard protocol used to exchange infor-mation between Web service providers andconsumers. SOAP communication consists ofsending XML request messages to a service,which then returns an XML responsemessage.

SOA

See Service Oriented Architecture.

SOAP

See Simple Object Access Protocol.

Source code

In WPF, a collection of one or more humanreadable .java files, stored under the WebCon-tent/WEB-INF/work/source folder in yourproject.

Span tag

Used frequently in WPF to provide a locationfor placing WPF UI components (such asthose created by Button and Link builders) onHTML pages.

SQL

See Structured Query Language.

Structured Query Language (SQL)

A language that can be used to performactions on a relational database.

Stub

See Service stub.

488 Glossary

Page 526: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Stubbed service

See Service stub.

Style sheet

See Cascading Style Sheet.

Table

Forms the basis of relational databases andconsist of a series of records. A table can alsorefer to a matrix of data that is used to displaydata to users.

Tag

In the context of a markup language, a tag isan element used to denote information abouttext or data. In WPF, the <span> tag is used toinsert WPF design elements into HTML.

Test

In the context of WPF, testing an applicationis done by running it on either an applicationserver or portal server. WPF applications canalso be tested directly from the WPFDesigner.

UNID

See Universal ID.

Universal ID (UNID)

A value that uniquely identifies a Lotus Notesdocument across all replicas of a database.

Value setter

A Java class referenced from the Profile SetEditor, which enables you to set profile entryvalues at runtime.

Variable

An entity that holds a changeable value. Vari-ables can be used in Java code or in WPFmodels through the Variable builder or SharedVariable builder.

View (IDE)

Used in an Eclipse-based IDE to display ornavigate through information. You can oftenopen other editors from inside a view.

View (Domino)

In a Domino database, a list of documentsmatching certain criteria. Views are not analo-gous to tables in a relational database, as theydo not contain any data—they are simply usedto display a specific set of documents.

View (pattern)

In reference to the MVC design pattern, aview refers to the presentation layer of anapplication. Components that are part of theview layer (such as JSPs, image files, andstyle sheets) are usually separated from therest of the application. See also Model ViewController pattern.

WAR file

See Web archive.

WAS

See WebSphere Application Server.

Web application

A WPF application that can be run on anapplication server, without requiring a portal(contrary to a portal application that requires aportal server). Note that a Web application isnot the same thing as a WebApp, which is aprofile-specific instance of a WPF application(see also WebApp).

Glossary 489

Page 527: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Web archive (WAR)

A .war file that contains all of the filesrequired for a Web application. WAR files canbe viewed using most compression utilitiesand are deployed to an application server orportal server.

Web server

Provides Web pages that can be accessed overthe Web through a browser. Web servers arenot in themselves sufficient to host WPFapplications, which require an applicationserver or portal server.

Web service

A service that can be communicated with overa network. WPF can be used to create, call,and consume Web services. In WPF, Web ser-vices are invoked via a SOAP request mes-sage, usually over HTTP, and are oftendefined in a WSDL document. The Web ser-vice performs an operation specified in therequest and returns a SOAP response messageto the caller.

Web Services Definition Language(WSDL)

An XML document used to describe a Webservice. Web services that communicate viaSOAP usually provide a WSDL, which con-sumers can then access to understand what theservice does and how it should be communi-cated with.

WEB-INF

The WEB-INF directory in a WPF projectcontains resources to make available to yourapplication. Files in the WEB-INF directorycannot be accessed directly in a URL—if youwant a file to be directly accessible to users,store it outside the WEB-INF directory in theWebContent directory.

WebApp

A profile-specific, executable instance of aWPF application. The WebApp is automati-cally created by the Factory generationengine. See also Factory generation engine.

WebApp Diagram

A graphical display of the execution flow usedin an application’s WebApps. The WebAppdiagram can be accessed via the WebApp Dia-gram tab in the Model Editor.

WebApp Tree

A hierarchical representation of the itemscontained in each WebApp, and can beaccessed via the WebApp Tree tab from theModel Editor in the WPF Designer.

WebContent

The WebContent directory in a WPF projectcontains all of the design artifacts for theproject. Files in the WebContent directory aredirectly servable to clients (with the exceptionof the contents of the WEB-INF directory).The WebContent directory is sometimesreferred to as the servable content directory inthe WPF documentation.

WebEngineServlet

See Factory controller servlet.

WebSphere Application Server

A J2EE-compliant application server that pro-vides a number of powerful features for man-aging applications in an SOA.

WebSphere Portal Server

A J2EE-compliant server that provides infra-structure and services for running portlets.

490 Glossary

Page 528: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

WebSphere Portlet Factory (WPF)

A broad term used to refer to the WPFDesigner development tool, as well as thearchitectural framework it provides (consist-ing of models, profiles, and builders). Theterms WebSphere Portlet Factory and Web-Sphere Portlet Factory Designer are normallyused interchangeably.

WebSphere Portlet Factory Designer

A tool for Eclipse-based IDEs that facilitatesrapid application development. Installing theDesigner gives you access to WPF-specificdesign artifacts, such as models, builders, andprofiles.

WebSphere Portlet Factory perspective

Contains a layout of editors and views for anEclipse-based IDE, which is well suited toWPF development.

WebSphere Portlet WAR

A portlet application created in WPF, nor-mally deployed to a WebSphere Portal Server.Deployment options for the WebSphere Port-let WAR are specified in the portal serverdeployment configuration. The WebSpherePortlet WAR can be used both in testing orstaging environments, as well as in productionenvironments.

WebSphere Property Broker

Acts as an intermediary to facilitate inter-port-let communication. Portlets can trigger eventsthat are picked up by the Property Broker, andother portlets can then respond to theseevents.

Wire

A link established between two portlets.Portlets that have been wired together can

send information to each other. The process ofsetting up a wire between two portlets is oftencalled wiring.

Workspace

An Eclipse-based IDE contains preferencesfor the IDE itself, as well as all of the projectsyou are currently working on.

WPF

See WebSphere Portlet Factory.

WPF Designer

See WebSphere Portlet Factory Designer.

WPS

See WebSphere Portal Server.

WSDL

See Web Services Description Language.

XML

See Extensible Markup Language.

XML Document

XML data is stored in XML documents,which are hierarchically organized collectionsof XML elements and attributes. See alsoExtensible Markup Language.

XML Namespace

Provides a unique context for XML attributesand elements. Otherwise, identical XMLidentifiers can be individuated using differentXML namespaces.

XML Schema

An XML Schema document defines a set ofrules for XML documents. XML schemas areoften used in WPF to define data sets.

Glossary 491

Page 529: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

This page intentionally left blank

Page 530: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

493

Index

SYMBOLS

{ } (curly braces), 199

A

accessingDomino Data Access builder,

434-436information and services, 3portals, 441-443target pages, 443Web services, 467

Action List builder, 6calls, adding, 43charts, 271conditional statements,

inserting, 197Java, 200project portlets, 299sales chart portlets, 274

actionsadding, 169, 179assets, adding lists to

retrieve, 112Click Actions,

configuring, 285comments, saving, 363-365

configuring, 190defining, 157errors, adding, 379post-save, 318-321Property Broker Action,

185-192salesAreaPage, adding, 285

Add Counter Column checkbox, 123

Add Item buttons, testing, 232adding

Action List builder calls, 43actions, 169

to retrieve lists of assets, 112

salesAreaPage, 285agents, 420, 424Ajax Type-Ahead

capabilities, 360Area Select fields, 359-360arguments, 186asset data, 110-111buttons, 158Calendar Picker builders, 154charts, 275Checkbox builders, 156Checkbox Group

builders, 155

comments to project portlets, 297

confirmation pages, 158, 300create functionality, 69-72CSSs, 144-146Data Column Modifier

builders, 127-128Data Field Modifier builders,

129-130, 316Data Hierarchy Modifier

builders, 128data sources, 453date expressions, 307default message pages, 179delete functionality, 66-68,

85-87division variables, 374drill-down capabilities,

279-287drop-down lists, 308drop-down select boxes, 154dynamic validation, 309English announcements, 335errors

actions, 379flags, 378handlers, 379pages, 377

Page 531: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

494 Index

feedback bars, Dojo, 367-369fields, 432Form Layout builders,

131-132formatter class, 312-315forms, 299functionality, 348-350,

413-423hidden inputs, 156HTML, 139images

builders, 159buttons, 160

interfaces, 179JAR files, 235-236links, 160, 185, 301LJOs, 217, 315loan data, 168lookups, 428main actions, 179methods, 170multiple models, 45-48order data, 246pages, 284-285, 443pagination, 122performance data, 347-348Portlet Adapters

custom builders, 401project portlets, 297survey portlets, 153-160

project portlets, 299, 303-309Radio Button Group

builder, 154regular expressions, 308resource bundles, 316-318Rich Data Definition

builders, 304roster data, 42sales data, 270-271schemas, 109-110, 271, 298Service Definition

builders, 109Service Operation builders,

251-252service operations,

43-44, 257

shopping carts, 222-228Spanish announcements,

335-336submit buttons, 299

functionality, 261, 359temporary variables, 280text

areas, 155inputs, 153

tooltips, Dojo, 366UI controls, 149-151update functionality, 65-66variables, 157

loandID, 190order stock portlets, 260project portlets, 299

XML Converters, 217-218addShoppingCartItem operation

implementing, 229testing, 225

ADDSPACES, 315addSupplierToMMDataSource

operation, 420, 424agents, Notes, 419aggregation of information, 3Ajax (Asynchronous Java and

XML), xxviiiapplying, 345-346performance, 398performance portlets,

354-362service providers, 346-353

functionality, 348-350performance data,

347-348testing, 353

announcement portletscreating, 325

default resource bundles, 327

ES Spanish resource bundles, 328

modifying pages, 326-327Portlet Adapters, 327US English resource

bundles, 327English, 335

headings, 334importing, 336models, 326profiling inputs, 331-332restricting, 339-340selection handlers, 332-333Spanish, 335-336testing, 337-342viewing, 336

APIs (Application ProgrammingInterfaces), Java, 202-203

HttpServletRequest, 209HttpServletResponse, 209IXml, 208RequestInputs, 207Variables, 206-207WebAppAccess, 203

appearance, customizing, 108-119

Application Programming Interfaces. See APIs

applicationsdebugging, 380

Eclipse, 382-384statements, 381-382

error handling, 371HelloWorld, 28Java. See Javalogging, 385

customizing, 388debug tracing, 385-387server statistics, 389-390

performance, 393Ajax, 398builder calls, 395caching, 394custom builders, 399-408data set size, 395Dojo, 398profiling, 398session size, 395-398

server deployment configuration, 22

service consumerscreating, 45-47testing, 47-48

Page 532: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 495

service provider/consumer patterns

applying, 49-50implementing, 37-39

service providers, 39-45stub services, 48testing, 31-34WPF

architecture, 5builders, 5deployment

configurations, 12-13generating WebApps, 7, 9models, 6-7overview of, 4profiles, 7WAR files, 11-12

applyingagents, Notes, 419Ajax, 345-346

performance portlets, 354-362

service providers, 346-353data services, 53-54Dojo, 362

enabling, 363feedback bars, 367-369saving comments,

363-365tooltips, 366

HTML templates, 141-142inter-portlet

communication, 192IXml interfaces, 250properties, 464-465

accessing Web services, 467

configuring Dominoservers, 465

debugging, 470dynamic class loading,

466-467event logging, 471logging, 469page automation, 472server statistic

logging, 471

specifying alternate compilers, 466

troubleshooting, 468uploading files, 466WPF caches, 468

service provider/consumerpatterns, 49-50

stub services, 102-104Web pages, 132

HTML builders, 133-134HTML templates,

136-142JavaScript builders,

135-136JSP builders, 135

architectureSOA, 37WPF, 5

builders, 5deployment

configurations, 12-13generating WebApps, 7, 9models, 6-7profiles, 7WAR files, 11-12

Area Select fields, adding, 359-360

areas, adding text, 155arguments

adding, 186configuring, 188deleting, 190

artifacts, generating custombuilder, 404

assetsdata, adding, 110-111lists, adding actions to

retrieve, 112pagination, adding, 122portlets

creating, 114-116testing, 117-119

schemas, adding, 109-110viewing, 114-116

assigning source fields, 230Asynchronous Java and XML.

See Ajax

attachments, Domino, 434Attribute Setter, configuring, 368authentication, configuring, 456automation, 5

deployment, 26pages, 472software, xxviiUI controls, 149-151

B

bandwidth limitations, 3Bean Manager, 210-216beans (Java), 210-216benefits

of portals, 3of WPF, 4-5

best practices, 5Booth, Jonathan, xvii-xviiiBowstreet, xxviibowstreet.properties file, 462breadcrumbs.html template, 138builders, 5

Action Listcharts, 271inserting conditional

statements, 197Java, 200sale chart portlets, 274

Cache Control, 394Calendar Picker, 154calls, 395Checkbox, 156Checkbox Group, 155Cooperative Portlet Source,

175-176, 185Cooperative Portlet

Target, 180customization, 399-408Data Field Modifier, 316Data Page, 118Data View, 118Debug Tracing, 385, 387Domino Data Access, 85-86,

434-436Domino View & Form, 119Form Layout, 131-132

Page 533: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

496 Index

HTML, 133-134images, 159input profiles, 323-325JavaScript, 135-136JSP, 135managing, 153Method, 200-201modifiers, 122

adding Form Layoutbuilders, 131-132

Data Column Modifier,122-124

Data Field Modifier, 124-126

Data Hierarchy Modifier, 124

Form Layout, 127-130testing, 130

New Model Wizard, 410Paging Buttons, 120Portlet Adapters

configuring, 65order stock portlets, 260sales chart portlets, 274shopping cart portlets,

creating, 228Radio Button Group, 154Rich Data Definition,

294-295, 304Schema, 244Service Consumer, 260, 275Service Definition, 109Service Operation, 251-252SQL Call, 60Style Sheet, 144-146Terms & Conditions, 401Terms & Conditions

Builder, 408Transform, 281types of, 401View & Form, 66, 115-116Web Charts, 268-272XML transformations,

263-264

buildingportlets, 21-26

creating models, 30-31manual deployment,

26-29testing applications, 31-34

projects portlets, 296Action Lists, 299comments, 297confirmation pages, 300formatting, 303-309forms, 299inputs, 301links, 301models, 296modifying pages, 297Portlet Adapters, 297schemas, 298submit buttons, 299-300testing, 302-311variables, 299

business functions, integrationof, 3

buttonsadding, 158images, 160paging, modifying, 120-122

C

C2A (click-to-action), 191Cache Control builder, 394caches, WPF, 468Calendar Picker builder,

adding, 154calls

builders, 395Web services, 256

capabilities of WPF, 5Cascading Style Sheets.

See CSSscategorized views, 428-432Chart Properties section, 277

charts, 268adding, 275customizing, 288-291drill-down capabilities,

279-287pages, 284-285sales chart portlets, 273-278service providers, 269-272Web Charts 3D Designer, 290

Checkbox builders, adding, 156Checkbox Group builders,

adding, 155checkboxes, modifying values,

358-359Choose Reference dialog box,

43, 200classes

dynamic class loading, 466-467

formatters, 295adding, 312-315CustomFormatter

class, 315Data Field Modifier

builder, 316LJOs, 315writing, 312

Javabeans, 210creating beans, 210-216

Java interfaces, 198MyException, 376ShoppingCartItemManager,

213-216StandardFormatter, 295

Clear Cart button, testing, 233clearing shopping carts, 218clearShoppingCartItem operation

implementing, 229testing, 226

Click Actions, configuring, 285click-to-action (C2A), 191client-side validation, 295clients, enabling HTTP, 444-445

Page 534: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 497

cluster.properties file, 462code

Java, 195. See also Javapost-save action, modifying,

319-320collaboration between users, 3columns

configuring, 123viewing, 357-358

commands, Java, 200comments

project portlets, 297saving, 363-365

common Notes functionality,adding, 413-423

communicationAjax, 345-346

performance portlets, 354-362

service providers, 346-353configuring, 185inter-portlet, 166

applying, 192Property Broker, 166-180,

182-184Property Broker Action,

185-192compiles, specifying

alternate, 466conditional statements, 197configuration

actions, 190announcements

default resource bundles, 327

English, 335ES Spanish resource

bundles, 328headings, 334importing, 336localizing headings, 328models, 326modifying pages, 326-327Portlet Adapters, 327

profiling Country inputs, 332

profiling language inputs,329-331

restricting, 339-340selection handlers,

332-333Spanish, 335-336testing, 337-342US English resource

bundles, 327viewing, 336

arguments, 188Attribute Setter, 368authentication, 456automatic deployment, 26Click Actions, 285columns, 123communication, 185CSSs, 142-146data page validation, 303data sets, sizing, 395Data Transformation,

276-277debugging

Eclipse, 382-384tracing, 470

deployment, 12-13detail portlets, 177-182Domino, 465

adding delete operations,85-87

creating service providers,82-85

environments, 79-80properties files, 80-81testing connections, 81-82testing service providers,

88-90drivers, 453environments, 439

accessing portals, 441-443DB2, 446-447installing WPFs, 439-440

JDBC resources, 451-459Lotus Domino, 443-445SQL Server, 448-450

events, logging, 471fields, 293-294

client-side/server-side validation, 295

formatter classes, 295modifying, 305schemas, 294-295

files, uploading, 466Java beans, 210-216list portlets, 173-177loanDetail models, 191log4j logging, 469logging, 385

customizing, 388debug tracing, 385-387server statistics, 389-390

modelsJava, 217Order Stock Web

services, 243New Model wizard, 409-410new target pages, 441-443page automation, 472performance portlets,

354-362portals, 2Portlet Adapters, 47, 175portlets, 21-26

adding functionality, 65-72

assets, 114-116contacts, 63-65creating models, 30-31manual deployment,

26-29Portlet Adapter builder, 65suppliers, 91-100survey, 151-163testing, 31-34, 72-74

post-save actions, 318-321

Page 535: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

498 Index

project portlets, 296Action Lists, 299comments, 297confirmation pages, 300formatting, 303-309forms, 299inputs, 301links, 301models, 296modifying pages, 297Portlet Adapters, 297schemas, 298submit buttons, 299-300testing, 302-311variables, 299

Property Broker, 183-184readSupplierRating, 417rich text, 433servers, logging, 471service consumers

creating, 45-47testing, 47-48

Service Definition builders, 41

Service Operation builders, 44

service providers, 39-44, 54Ajax, 346-353creating models, 54-55customizing portlet

appearances, 108-113defining services, 55inter-portlet communica-

tion, 167-172specifying operations,

55-59testing, 44-45, 60-63

sessions, sizing, 395-398shopping cart portlets,

226-232models, 226-228Portlet Adapters, 228testing, 232-235

stockView builder calls, 426stubs, 48, 103-104switchToReturns builder

call, 430

troubleshooting, 25UI controls, 149-151Web services

Order Stock, 242-253, 255order stock portlets,

258-263service providers, 255-258

WPF caches, 468confirmation pages

adding, 158project portlets, 300

connectionsDomino, testing, 81-82JDBC resources, configuring,

451-459testing, 23

consuming, 114addSupplierToMMData-

Source operations, 422performance portlets, 356readReturnsView

operations, 429readStockView operations,

427-428readSupplierRating

operations, 417contacts

editing, 73portlets

adding functionality, 65-72

creating, 63models, 64-65Portlet Adapter builder, 65testing, 72-74

controllers, 50controls

pagination, adding, 122User Interface in WPF,

149-151Cooperative Portlet Source

builders, 175-176, 185Cooperative Portlet Target

builders, defining, 180coordinators, modifying,

407-408

country inputs, profiling, 332create functionality

adding, 69-72suppliers models, adding, 97

Create Portlet Factory Projectwizard, 24, 30

createContact operation, testing, 63

createSupplierDocumentoperation, testing, 90

CSSs (Cascading Style Sheets),142-146

curly braces ({ }), 199CustomFormatter class, 315customization

builders, 399-408charts, 288-291exceptions, 376-377HTML templates, 141-142logging, 388portlet appearance, 108-119validation, 316

modifying regular expres-sion messages, 318

post-save actions, 318-321resource bundles, 316-318

WPF, 107

D

Data Column Modifier builders,122-128

Data Field Modifier builders,100, 124-130, 316, 432

Data Hierarchy Modifierbuilders, 124, 128

data modifiers, 122Data Column Modifier

builders, 122-124Data Field Modifier builders,

124-126Data Hierarchy Modifier

builders, 124Form Layout builders,

127-132testing, 130

Data Page builders, 118

Page 536: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 499

data page validation, configuring, 303

data services, applying, 53-54data sets, sizing, 395Data Transformation calls,

276-277Data View builder, 118databases

data sources, adding, 453navigating, 444-445pagination, 119

modifying paging buttons,120-122

starting, 120testing, 446-450

dataEntryPageTable style, 145dates, adding expressions, 307DB2 databases, creating,

446-447, 454Debug Configuration dialog

box, 384debugging, 380

Eclipse, 382-384statements, 381-382tracing, 385-387, 470

default message pages, adding, 179

default resource bundles, 327default selection handlers, 324defining

actions, 157division processes, 374-375events, 187inputs, 403request objects, 243response objects, 245services, 41, 55, 83, 168

Ajax, 347charts, 270Java, 217Order Stock Web

services, 243XML transformations, 280

delete functionalityadding, 66-68suppliers models, 94-95

Delete Item button, testing, 233

delete operations, adding, 85-87deleteContact operation,

testing, 63deleteShoppingCartItem

operationimplementing, 230-232testing, 226

deleteSupplierDocumentoperation, testing, 90

deletingevents, 190fields, 99-100, 432shopping carts, 223-224

deploymentautomatic, 26configuration, 12-13licenses, upgrading, 291-292portals, 441-443portlets, manual, 26-29troubleshooting, 25WAR files, 12

Deployment Configuration dialog box, 25

design, patterns, xxvii. See alsoconfiguration

detail portlets, inter-portlet communication, 177-182

developmentautomation, 5faster development times, 4Java, 196-198WAR files, 11

dialog boxesChoose Reference, 43, 200Debug Configuration, 384Deployment Configuration, 25Edit Profile, 333Make Assignment, 191Profile Input, 329Run, 31Select a Wizard, 327Select Action, 43, 97

DIIOP tasks, starting, 444directories, 19-20displayPageTable style, 145displayResult model, 375

division process, error handling,374-375

documentsCSSs, 142-146pagination, 119

modifying paging buttons,120-122

starting, 120sorting, 264XML, modifying with

Java, 198Dojo, 362

comments, saving, 363-365enabling, 363feedback bars, adding,

367-369performance, 398tooltips, adding, 366

Dominoattachments, 434connections, testing, 81-82Notes functionality, 78-79properties files, configuring,

80-81servers, configuring

environments, 79-80, 465service consumers, testing,

100-101service providers

adding delete operations,85-87

creating, 82-85testing, 88-90

stub service, 102-104Domino Data Access builders, 5,

85-86, 434-436Domino View & Form

builders, 119drill-down capabilities, adding,

279-287drivers, configuring, 453drop-down lists, adding, 308drop-down select boxes,

adding, 154dynamic class loading, 466-467dynamic validation, adding, 309

Page 537: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

500 Index

E

Eclipsedebugging, 382-384IDEs, 17

Edit Profile dialog box, 333editing, 17, 73editors, 17elements

filtering, 263loans, selecting, 180renaming, 264WPF architecture, 5

builders, 5deployment configura-

tions, 12-13generating WebApps, 7-9models, 6-7profiles, 7WAR files, 11-12

XML, searching, 208enabling

Dojo, 363HTTP clients, 444-445

End Item button, testing, 233English announcements,

adding, 335entries, profiles, 330environments

configuring, 439accessing portals, 441-443creating test databases in

DB2, 446-447creating test databases in

SQL Server, 448-450installing WPFs, 439-440JDBC resources, 451-459Lotus Domino, 443-445

Domino, configuring, 79-80error handling, 371-373

displayResult model, 375division process, 374-375division variables, 374exceptions

customizing, 376errors, 376-379throwing, 377

models, 373-374results pages, 374testing, 375-376, 380

errorMessage style, 145errors, deployment

configuration, 25ES Spanish resource bundles,

creating, 328events

defining, 187deleting, 190handling, 189inter-portlet communication,

181-182logging, 471models, 186triggering, 187

exceptionscustomizing, 376throwing, 377

excluding JARs from WAR files,235-236

execution of WebApps, 7, 9expressions

dates, adding, 307regular

adding, 308messages, 318

Extensible Markup Language.See XML

extensibility, inter-portletcommunication, 166

F

Factory generation engine, 5feature sets, specifying, 22features, xxviifeedback bars, adding, 367-369fields, 293-294

Area Select, adding, 359-360client-side/server-side

validation, 295deleting, 99-100, 432formatter classes, 295hide-when, 433

modifying, 305ProjectBudget,

modifying, 308ProjectManager, adding

drop-down lists, 308schemas, 294-295source, assigning, 230stockSupplied, 424testing, 309-311

fifth operations, specifying, 58-59

filesJAR, importing, 234-236length limitations, 468properties, 80-81, 461-464uploading, 466WAR, 4, 11-12, 235-236web.xml, modifying, 19

filtering elements, 263first operations, specifying, 55flags, adding error, 378folders

WebContent, 19WebSphere Portlet Factory

Designer, 17-21Form Layout builders, 127-132formatter classes, 295

adding, 312-315CustomFormatter class, 315Data Field Modifier

builder, 316LJOs, 315writing, 312

formatting. See alsoconfiguration

data sets, sizing, 395fields, 293-294

client-side/server-side validation, 295

formatter classes, 295schemas, 294-295

headers, 334project portlets, 303-309rich text, 433sessions, sizing, 395-398

forms, project portlets, 299

Page 538: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 501

formulas, Notes, 414-417fourth operations, specifying,

57-58functionality

Ajax, 348-350create

adding, 69-72suppliers models, 97

custom builder, modifying,405-406

deleteadding, 66-68suppliers models, 94-95

formatter classesadding, 312-315CustomFormatter

class, 315Data Field Modifier

builder, 316LJOs, 315writing, 312

Notes, 78-79, 413-423overwriting, 200performance, adding,

351-352submit, adding, 261, 359update

adding, 65-66suppliers models, 94

functions, 38

G

general logging, configuring, 469generation of WebApps, 7-9getAssetsList operation, 112getContactDetail operation, 62getDocumentData( )

method, 436getDominoDatabase( )

method, 435getDominoSession( )

method, 435getLoanDetail operation,

specifying, 171getLoansList operation,

specifying, 170

getPerformanceData operation,350-353

getSales operation, 271getSalesArea operation

specifying, 283testing, 284

getUserName( ) method, 435GreenPoint Web Chart Builder

feature set, 269gridTable style, 145gridtable.html HTML templates,

modifying, 140

H

hand coding, reducing need for, 4handlers

errors, 379selection, 324, 332-339

handlingerrors, 371, 373

adding, 376-379customizing

exceptions, 376displayResult model, 375division process, 374-375division variables, 374models, 373-374results pages, 374testing, 375-376, 380throwing exceptions, 377

events, 189inter-portlet communication,

181-182headers, formatting, 334headings, localizing announce-

ment, 328Hello World!

building, 21-26starting, 28testing, 31-34

hidden inputs, adding, 156hide-when fields, 433hiding columns, 357-358

HTML (Hypertext Markup Language)

builders, 133-134order stock portlets, 259templates, 136-142UI controls in WPF, 150

HTTP (Hypertext Transfer Protocol)

Clients, enabling, 444-445tasks, starting, 444

HttpServletRequest interfaces,200, 209

HttpServletResponse interfaces,200, 209

I

IDEs (Integrated DevelopmentEnvironments), 4, 17

Eclipse, 17IInputFieldFormatter

interface, 312images

builders, adding, 159buttons, adding, 160

implementationaddShoppingCartItem

operation, 229clearShoppingCartItem

operation, 229deleteShoppingCartItem

operation, 230-232service provider/consumer

patterns, 37-39updateShoppingCartItem

operation, 228-229importing

announcements, 336JAR files, 234-236

informationaccessibility of, 3aggregation of, 3testing, 408

inline Java, 198-200

Page 539: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

502 Index

inputhidden, adding, 156text, adding, 153viewing, 160

inputsbuilders, profiles, 323-325Country, profiles, 332defining, 403languages, profiles, 329-331overriding, 227project portlets, 301

installing WPFs, 439-440Integrated Development

Environments (IDEs), 4, 17integration

of business functions, 3capabilities, 5

inter-communication, PropertyBroker Action, 185-192

inter-portlet communication, 166applying, 192events, handing, 181-182Property Broker, 166-167

configuring, 183-184detail portlets, 177-182list portlets, 173-177service providers, 167-172

interfacesadding, 179controls in WPF, 149-151IInputFieldFormatter, 312IXml, applying, 250Java, 198-203

HttpServletRequest, 209HttpServletResponse, 209IXml, 208RequestInputs, 207Variables, 206-207WebAppAccess, 203

order stock portlets, 260performance portlets, 357personalization, 4portals, 2WebSphere Portlet Factory

Designer, 13-17

itemssales, retrieving, 282-283shopping carts

adding, 222creating, 211-213deleting, 223-224updating, 223viewing, 221

IXml interface, 208, 250

J

J2EE (Java 2 Enterprise Edition), xxix

JAR files, importing, 234-236Java

APIs, 202-203HttpServletRequest, 209HttpServletResponse, 209IXml, 208RequestInputs, 207Variables, 206-207WebAppAccess, 203

beans, 210-216interfaces, 198portlets

Action Lists, 200development, 196-198inline Java, 198-200LJO, 201-202Method builder, 200-201methods, 198

service providers, 216LJOs, 217models, 217services, 217shopping carts, 218-224testing, 224-226XML Converters. adding,

217-218shopping cart portlets

creating, 226-232testing, 232-235

Java 2 Enterprise Edition (J2EE), xxix

JavaScriptbuilders, 135-136validation, 295

JDBC resources, configuring,451-459

jdbcDrivers.properties file, 462JRE system library, Project

Explorer view, 19JSPs (Java Server Pages), 135

K–L

keyword lookups, 424-428

label style, 145labelCell style, 145language inputs, profiling,

329-331LDAP (Lightweight Directory

Access Protocol), 4length limitations, files, 468licenses, upgrading deployment,

291-292Lightweight Directory Access

Protocol. See LDAPlimitations

bandwidth, 3file length, 468

Linked Java Object (LJO), 200-202

linksadding, 160, 185project portlets, 301

lists, 54categorized views, 428-432drop-down, adding, 308inter-portlet communication,

173-177LJOs (Linked Java Objects),

200-202adding, 315Java, 217

loading dynamic classes, 466-467

loan data, adding, 168

Page 540: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 503

loanDetail model, configuring, 191

loanID variables, adding, 190loans

actions, adding, 169elements, selecting, 180

localizing announcement headings, 328

log4jlogging, 469properties file, 462

logging, 385customizing, 388debug tracing, 385-387events, 471server statistics, 389-390, 471

logging.properties file, 462lookups, keywords, 424-428Lotus Collaboration Extension

feature set, 80Lotus Domino, configuring,

443-445Lotus Notes, 4

M

main actions, adding, 179maintainability, inter-portlet

communication, 166Make Assignment dialog

box, 191Manage Pages link, 442management

Bean Manager, 210-216builders, 153

manual deployment, portlets, 26-29

mapping to remote servers, 13messages, 23

debug, logging, 388regular expressions,

modifying, 318Method builder, 200-201methods

adding, 170Domino Data Access builder,

434-436

Java, 198Action List builder,

enabling through, 200inline, 198-200viewing, 196

migrate-profilesets.propertiesfile, 462-463

minimum scale values, specifying, 277

Model Editor, 15, 47Model View Controller. See MVCModel XML tab, 15models, 6-7, 49

Ajax, 347announcements portlets, 326assets, testing, 117charts, 269contact portlets, creating,

63-65creating, 30-31, 40, 46,

109, 114custom builders, 400debugging, 384detail portlets, 178displayResult, 375error handling, 373-374events, 186information, 408inter-portlet

communication, 168Java, 196, 217list portlets, creating, 173multiple

adding, 45-47testing, 47-48

New Model wizard, creating,409-410

order stock portlets, 259Order Stock Web

services, 243performance portlets, 354Project Explorer view, 18project portlets, 296sales chart portlets, 273service providers, creating,

54-55, 82-85

shopping cart portlets, creating, 226-228

stubs, creating, 48, 103-104suppliers

adding functionality, 94-97

creating, 91-92deleting fields, 99-100Portlet Adapter, 93-94

survey portlets, creating, 151modification

Action List project portlets, 299

checkbox values, respondingto, 358-359

coordinators, 407-408custom builder functionality,

405-406fields, 305, 308pages

announcements portlets,326-327

custom builders, 400order stock portlets, 259performance portlets, 355projects portlets, 297sales chart portlets, 273survey portlets, 152

paging buttons, 120-122post-save action code,

319-320property files, 461regular expression

messages, 318results pages, 374submit buttons, 300, 304UI controls, 149-151web.xml files, 19

modifiers, 122Data Column Modifier

builders, 122-124Data Field Modifier builders,

124-126Data Hierarchy Modifier

builders, 124Form Layout builders,

127-132testing, 130

Page 541: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

504 Index

multiple modelsadding, 45-47testing, 47-48

MVC (Model View Controller), 49MyException class, 376

N

namespaces, XML, 241navigation

databases, 444-445Eclipse IDEs, 17JDBC Providers link, 451WebSphere Portlet Factory

Designer, 13-21New Deployment Configuration

window, 24New Model Wizard, 46, 409-410new target pages,

configuring, 441non-schema typed fields,

294-295Notes

environments, configuring,79-80

functionality, 78-79, 413-423properties files, configuring,

80-81

O

objectsLJOs, 200requests, defining, 243responses, defining, 245

openingJAR files, 235-236Page menus, 183Web Modules pages, 29

Operation Results section, 416operations, 38

adding, 43-44addShoppingCartItem

implementing, 229testing, 225

addSupplierToMMDataSource,420, 424

clearShoppingCartItemimplementing, 229testing, 226

createContact, testing, 63createSupplierDocument,

testing, 90definition of, 39delete, adding, 85-87deleteContact, testing, 63deleteShoppingCartItem

implementing, 230-232testing, 226

deleteSupplierDocument,testing, 90

detail portlets, 177-182fifth, specifying, 58-59first, specifying, 55fourth, specifying, 57-58getAssetsList,

specifying, 112getContactDetail, testing, 62getLoanDetail,

specifying, 171getLoansList, specifying, 170getPerformanceData,

specifying, 350, 353getSales, specifying, 271getSalesArea

specifying, 283testing, 284

list portlets, 174-177readReturnsView, 428-430readStockView, 425-428readSupplierDocument,

testing, 89readSupplierRating, 415-417readSupplierView, testing, 88retrieveContactsView,

testing, 61second, specifying, 55-56service, adding, 257setContact, testing, 63specifying, 83third, specifying, 56-57updatePerformanceData,

specifying, 352

updateShoppingCartItemimplementing, 228-229testing, 226

updateSupplierDocument,testing, 90

viewShoppingCart, testing, 225

viewShoppingCartItem, testing, 225

optimization of performance, 393Ajax, 398builder calls, 395caching, 394custom builders, 399-408data set size, 395Dojo, 398profiling, 398session size, 395-398

order data, adding, 246order stock portlets, creating,

258-263orderStockWebService Web

service, testing, 252-255outputData style, 145outputDataCell style, 145overriding inputs, 227overwriting functionality, 200

P

Page menu, opening, 183pageprocessors.properties

file, 462pages

adding, 443announcements portlets,

modifying, 326-327automation, 472charts, adding, 284-285confirmation, adding,

158, 300CSSs, 142-146custom builders,

modifying, 400default message, adding, 179errors, adding, 377headers, formatting, 334

Page 542: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 505

new target, configuring, 441-443

order stock portlets, 259performance portlets,

modifying, 355portals, configuring, 2projects portlets,

modifying, 297results, error handling, 374sale chart portlets,

modifying, 273salesAreaPage,

populating, 285survey portlets,

modifying, 152target, accessing, 443Web Modules, opening, 29

pagination, 119modifying, 120-122starting, 120

pagingassistants, 119buttons, 139-140

Paging Buttons builder, 120patterns

design, xxviiMVC, 49service provider/consumer,

37-39, 49-50performance, 393

Ajax, 347-348, 398builder calls, 395caching, 394custom builders, 399-408data set size, 395Dojo, 398portlets, creating, 354-362profiling, 398session size, 395-398updating, 351-352

permissions, 443persistentstore.properties

file, 462personalization of user

interfaces, 4

perspective, 17WebSphere Portlet Factory

Designer, 13population, salesAreaPage

pages, 285portals

benefits of, 3configuring, 441-443Notes functionality, 78-79overview of, 2servers, 23

Portlet Adaptersadding, 114announcements portlets, 327configuring, 47, 65custom builders, 401list portlets, creating, 175order stock portlets, 260performance portlets, 355project portlets, 297sales chart portlets, 274shopping cart portlets, 228suppliers model, creating,

93-94survey portlets, adding,

153-160portlets

appearance, customizing,108-119

assetscreating, 114-116testing, 117-119

building, 21-26creating models, 30-31manual deployment,

26-29testing applications, 31-34

charts, 268adding drill-down

capabilities, 279-287customizing, 288-291sales chart portlets,

273-278service providers, 269-272

contactsadding functionality,

65-72creating, 63models, 64-65Portlet Adapter builder, 65testing, 72-74

CSSs, 142-146detail, Property Broker,

177-182inter-portlet

communication, 166applying, 192Property Broker, 166-180,

182-184Java

Action Lists, 200APIs, 202-203beans, 210creating Java beans,

210-216development, 196-198HttpServletRequest

APIs, 209HttpServletResponse

APIs, 209inline Java, 198-200IXml APIs, 208LJO, 201-202Method builder, 200-201methods, 198RequestInputs APIs, 207shopping carts, 226-232service providers, 216-224testing service providers,

224-226testing shopping carts,

232-235Variables APIs, 206-207WebAppAccess APIs, 203

lists, Property Broker, 173-177

order stock, creating, 258-263overview of, 2performance, creating,

354-362

Page 543: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

506 Index

profiles, 323announcements portlets,

325-342builder inputs, 323-325

projectsbuilding, 296-309testing, 309-311

sales chart, 273-278suppliers

adding functionality, 94-97

creating, 91deleting fields, 99-100models, 91-92Portlet Adapter, 93-94

surveyadding Portlet Adapters,

153-160creating, 151models, 151modifying pages, 152testing, 160-163

WAR files, 11post-save actions, 318-321preliminary testing

profiled portlets, 337project portlets, 302-303

presentation tiers, 50Problems view, 17, 25productivity gains, xxviiProfile Input dialog box, 329Profile Set Editor, 332-333profiles, 7

entries, 330performance, 398portlets, 323

announcements portlets,325-342

builder inputs, 323-325Project Explorer view, 18

Project Explorer view, 17Project Properties dialog box, 26ProjectBudget field,

modifying, 308ProjectManager field, adding

drop-down lists, 308

projects, 17Hello World!, creating, 21,

23-26portlets

building, 296-309testing, 309-311

propertiesapplying, 464-465

accessing Web services, 467

configuring Dominoservers, 465

debugging, 470dynamic class loading,

466-467event logging, 471logging, 469page automation, 472server statistic

logging, 471specifying alternate

compilers, 466troubleshooting, 468uploading files, 466WPF caches, 468

charts, specifying, 277files, 80-81, 461-464

Property Broker, 166-167configuring, 183-184detail portlets, 177-182list portlets, 173-177service providers, 167-171

testing, 171-172Property Broker Actions,

185-192protocols

HTTP, 444-445LDAP, 4SOAP, 241, 467

providersdrivers, configuring, 453service

Ajax, 346-353charts, 269-272customizing portlet

appearance, 108-113

inter-portlet communica-tion, 167-172

Java, 216-218shopping carts, 218-224testing, 224-226Web services, 255-258

servicescreating, 54defining services, 55models, 54-55specifying operations,

55-59testing, 60-63

proxy access for Web services, 467

Q–R

RAD (Rational ApplicationDeveloper), 4

Radio Button Group builder,adding, 154

Rational Application Developer(RAD), 4

Rational Software Architect(RSA), 4

readReturnsView operation, 428-430

readStockView operation, 425-428

readSupplierDocumentoperation, testing, 89

readSupplierRating operation,415-417

readSupplierView operation,testing, 88

record pagination, 119modifying paging buttons,

120-122starting, 120

regular expressionsadding, 308messages, 318

remote servers, mapping to, 13removing. See deletingrenaming elements, 264request objects, defining, 243

Page 544: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 507

RequestInputs interface, 207requiredPrompt style, 145resource bundles

adding, 316-318announcements portlets, 327

ES Spanish, 328US English, 327

Resources, configuring JDBC,451-459

response objects, defining, 245restrictions

accessibility, 4announcements, 339-340

results pages, error handling, 374retrieveContactsView operation,

testing, 61Rich Data Definition builder,

294-295, 304rich text, 433roster data, adding, 42RSA (Rational Software

Architect), 4Run dialog box, 31running, post-save action

code, 321

S

saleschart portlets, 273-278data, adding, 270-271items, retrieving, 282-283schemas, adding, 271

salesAreaPage, populating, 285salesAreaPage, adding, 285saving

builder calls, 41comments, 363-365post-save actions, 318-321

scale values, specifying minimum, 277

Schema builder, 244schemas, 241

adding, 109-110, 271fields, 294-295project portlets, 298

searching XML elements, 208

second operations, specifying,55-56

sectionLabel style, 145sectionLabelCell style, 145segments, 333Select a Wizard dialog box, 327Select Action dialog box, 43, 97selecting loan elements, 180selection handlers, 324, 332-339selectLoan, running, 191sendDocument( ) method, 435server-side validation, 295server.properties file, 462servers

Ajax, 345-346performance portlets,

354-362service providers, 346-353

debugging, 383Domino

configuring, 79-80, 465properties files, 80-81testing, 81-82

Lotus Domino, 443-445remote, mapping to, 13statistics, 389-390, 471

Service Consumer builder, 260, 275

service consumerscreating, 45-47definition of, 39testing, 47-48, 100-101

Service Definition builders, 41, 109

Service Operation builders,adding, 251-252

Service Oriented Architecture.See SOA

service providers, 37-39, 49-50Ajax, 346-347, 350-353

functionality, 348-350performance data,

347-348testing, 353

charts, 269-272creating, 39-44definition of, 39

Dominoadding delete operations,

85-87creating, 82-85testing, 88-90

inter-portlet communication,167-172

Java, 216LJOs, 217models, 217services, 217shopping carts, 218-224testing, 224-226XML Converters, adding,

217-218portlets, 108-113testing, 44-45Web services, 255-258

servicesaccessibility of, 3Ajax, defining, 347charts, defining, 270consuming, 114data, applying, 53-54defining, 39-41, 83, 168Java, 217list portlets, specifying, 173operations, adding,

43-44, 257performance portlets,

consuming, 356providers. See service

providersstub

applying, 102-104creating, 48

Web, 240-241accessing, 467Order Stock, 242-255order stock portlets,

258-263service providers, 255-258

sessions, sizing, 395-398setComputeWithFormEnabled( )

method, 435setContact operation, testing, 63sharing variables, 189

Page 545: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

508 Index

shopping cartsadding, 222clearing, 218deleting, 223-224Java, creating, 211-213portlets

creating, 226-232testing, 232-235

updating, 223viewing, 219-221

ShoppingCartItemManagerclass, 213-216

Simple Object Access Protocol(SOAP), 241, 467

sizingdata sets, 395sessions, 395, 397-398

SOA (Service Oriented Architecture), 37

definition of, 39service provider/consumer

patternsapplying, 49-50implementing, 37-39

SOAP (Simple Object AccessProtocol), 241, 467

software automation, xxviisorting documents, 264source fields, assigning, 230Spanish announcements, adding,

335-336Specify Deployment Credentials

checkbox, 23specifying

alternate compilers, 466Chart Properties, 277fifth operations, 58-59first operations, 55fourth operations, 57-58getAssetsList operations, 112getLoanDetail operation, 171getLoansList operation, 170getPerformanceData

operations, 350, 353getSales operation, 271

getSalesArea operations, 283minimum scale values, 277operations, 83second operations, 55-56service list portlets, 173third operations, 56-57updatePerformanceData

operations, 352SQL Call builders, 60SQL Server

data sources, configuring, 455databases, creating test,

448-450StandardFormatter class, 295starting

HelloWorld applications, 28pagination, 120

statementsconditional, 197debugging, 381-382inline Java, 198-200

statisticsservers, 389-390servers, logging, 471

stockSupplied field, 424stub services

applying, 102-104creating, 48

Style Sheet builder, 144-146styles

charts, customizing, 288-291CSSs, 142-146

submit buttonsmodifying, 304project portlets, 299-300

submit functionality, adding,261, 359

Submit Order button, 261suppliers portlet

create functionality, adding, 97

creating, 91delete functionality, adding,

94-95fields, deleting, 99-100

models, creating, 91-92Portlet Adapters, configuring,

93-94update functionality,

adding, 94Suppliers view, 83survey portlets

adding Portlet Adapters, 153-160

creating, 151models, 151modifying pages, 152testing, 160-163

T

tableHead style, 145tableHeadRow style, 145tableHeadText style, 145tableRowEven style, 145target pages

accessing, 443configuring, 443

TargetSales, viewing, 289-290templates

breadcrumbs.html, 138HTML, 136-142

temporary variables, adding, 280Terms & Conditions builder,

401, 407-408TESTDB database, 54, 446testing

Add Item buttons, 232addShoppingCartItem

operations, 225announcements, 337applications, 31-34categorized views, 433Clear Cart button, 233clearShoppingCartItem

operations, 226connections, 23, 81-82contacts portlets, 72-74createContact operation, 63createSupplierDocument

operation, 90

Page 546: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 509

data modifiers, 130data sources, 458databases, 446-450Delete Item buttons, 233deleteContact operation, 63deleteShoppingCartItem

operations, 226deleteSupplierDocument

operation, 90detail portlets, 182division models, 375-380drill-down capabilities, 287End Item buttons, 233fields, 309-311getContactDetail

operation, 62getPerformanceData

operations, 353getSalesArea operations, 284information models, 408inter-portlet

communication, 184list portlets, 177New Model Wizard

Builder, 410order stock portlets, 262-263orderStockWebService Web

service, 252-255pagination, 120performance portlets,

360-362portlet assets, 117-119post-save actions, 321profiles, 341-342project portlets, 302-303,

309-311readSupplierDocument

operation, 89readSupplierView

operation, 88retrieveContactsView

operation, 61sales chart portlets, 278selection handlers, 338-339service consumers, 47-48,

100-101

service providers, 44-45, 60-63

Ajax, 353charts, 272customizing portlet

appearances, 113Domino, 88-90inter-portlet communica-

tion, 171-172Java, 224-226Web services, 258

setContact operation, 63shopping cart portlets,

232-235survey portlets, 160-163updateShoppingCartItem

operations, 226updateSupplierDocument

operation, 90viewShoppingCart

operations, 225viewShoppingCartItem

operations, 225text

areas, adding, 155inputs, adding, 153rich, 433

third operations, specifying, 56-57

throwing exceptions, 377tooltips, adding, 366tracing

debug, 385-387debugging, 470sessions, 396-398

Transform builder, 281transformations

defining, 280XML, 263-264

translationfields, 293-294

client-side/server-side validation, 295

formatter classes, 295schemas, 294-295

formatter classesadding, 312-315CustomFormatter

class, 315Data Field Modifier

builder, 316LJOs, 315writing, 312

Notes, 414-417project portlets, 303-309

triggering events, 187troubleshooting

configuration, 25debugging, 380

Eclipse, 382-384statements, 381-382

error handling, 371-373adding error actions, 379adding error flags, 378adding error handlers, 379adding error pages, 377customizing

exception, 376displayResult model, 375division process, 374-375division variables, 374models, 373-374results pages, 374testing, 375-376, 380throwing exception, 377

file length limitations, 468Type-Ahead capabilities (Ajax),

adding, 360types

of builders, 401of errors, 371

U

UIs (User Interfaces)controls in WPF, 149-151personalization, 4WebSphere Portlet Factory

Designer, 13-14, 17UNIDs (universal identifiers), 416unwanted fields, deleting, 99-100

Page 547: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

510 Index

update functionalityadding, 65-66suppliers models, adding, 94

updatePerformanceDataoperation, specifying, 352

updateShoppingCartItemoperation

implementing, 228-229testing, 226

updateSupplierDocumentoperation, testing, 90

updatingperformance, 351-352shopping carts, 223

upgrading deployment licenses,291-292

uploading files, 466US English resource bundles,

creating, 327Usability, inter-portlet

communication, 166User Interfaces. See UIsusers, collaboration between, 3

V

validationcustomization, 316

modifying regular expres-sion messages, 318

post-save actions, 318-321resource bundles, 316-318

dynamic, adding, 309fields, 293-294

client-side/server-side, 295formatter classes, 295schemas, 294-295

formatter classesadding, 312-315CustomFormatter

class, 315Data Field Modifier

builder, 316LJOs, 315writing, 312

JavaScript, 295Notes, 414-417project portlets, 303-309

valuescheckboxes, modifying,

358-359minimum scale,

specifying, 277Variable builder calls, adding,

110-111variables

adding, 157division, error handling, 374loanID, adding, 190order stock portlets, 260project portlets, 299sharing, 189temporary, adding, 280

Variables interface, 206-207View & Form builders, 66,

115-116, 138viewing

announcements, 336assets, 114-116columns, 357-358data in WPF, 118input, 160, 301interfaces

order stock portlets, 260performance portlets, 357

Java, 196shopping carts, 219-221TargetSales, 289-290

views, 17, 50categorized, 428-432Project Explorer, 17Suppliers, 83

viewShoppingCart operation,testing, 225

viewShoppingCartItem operation, testing, 225

W

WAR (Web ARrchive) files, 4,11-12

JARs, excluding from, 235-236

WAS CE (WebSphere Application Server CommunityEdition), 40

Web Charts 3D Designer, 290Web Charts builders, 268-272Web Modules pages, opening, 29Web pages

applying, 132CSSs, 142-146HTML

builders, 134templates, 138-141

JavaScript builders, 136Web services, 240-241

accessing, 467definition of, 39Order Stock, 242-255order stock portlets, 258-263service providers, 255-258

Web Services Description Language (WSDL), 241

WEB-INF directory, 20web.xml files, modifying, 19WebApp Diagram tab, 15WebApp Tree tab, 15WebAppAccess interface, 203WebApps, generating, 7, 9WebContent directory, 19WebContent/WEB-INF/work/

classes directory, 19WebSphere Application

Server Community Edition. See WAS CE

WebSphere Portlet FactoryDesigner

folder structure, 17-21overview of, xxix-xxxi, 13user interfaces, 13-17

WebSphere Portlet Factory. See WPF

Page 548: IBM.press.rapid.portlet.developme.with.WebSphere.portlet.factory.sep.2008

Index 511

windows, New Deployment Configuration, 24

wizards, 5Create Portlet Factory

Project, 24, 30New Model Wizard, 46,

409-410workspace, 17WPF (WebSphere Portlet

Factory)Ajax. See Ajax,architecture, 5

builders, 5deployment

configurations, 12-13generating WebApps, 7, 9models, 6-7profiles, 7WAR files, 11-12

benefits of, 4-5caches, 468charts, 268

adding drill-down capabilities, 279-287

customizing, 288-291sales chart portlets,

273-278service providers, 269-272

customizing, 107data modifiers, 122

adding Form Layoutbuilders, 131-132

Data Column Modifierbuilders, 122, 124

Data Field Modifierbuilders, 124-126

Data Hierarchy Modifierbuilders, 124

Form Layout builders,127-130

testing, 130data, viewing, 118debugging, 380

Eclipse, 382-384statement, 381-382

error handling, 371event models, 186installing, 439-440logging, 385

customizing, 388debug tracing, 385-387server statistics, 389-390

overview of, 4pagination, 119

modifying paging buttons,120-122

starting, 120performance, 393

Ajax, 398builder calls, 395caching, 394custom builders, 399-408data set size, 395Dojo, 398profiling, 398session size, 395-398

User Interface controls in,149-151

Web services, 240-241Order Stock, 242-255order stock portlets,

258-263service providers, 255-258

WSDL (Web Services Description Language), 241

X–Z

XML (Extensible Markup Language)

converters, adding, 217-218documents

modifying with Java, 198sorting, 264

elements, searching, 208namespaces, 241transformations,

263-264, 280