<<

. 54
( 87 .)



>>

* @param newChoice String
*/
public void addChoice(String newChoice) {

if (!newChoice.equals("")) {
newChoice = stripDelimiter(newChoice) + DELIMITER;
String newChoices = choices + newChoice;
setChoices(newChoices);
}
}

/**
* Delete a poll choice
* @param choiceIndex int
*/
public void deleteChoice(int choiceIndex) {
// Strip the choice from the choices string
int index = -1;
for (int i = 0; i < choiceIndex; i++) {
index = choices.indexOf(DELIMITER, index + 1);
}

String prefix = choices.substring(0, index + 1);
index = choices.indexOf(DELIMITER, index + 1);
String suffix = choices.substring(index + 1);
String newChoices = prefix + suffix;

setChoices(newChoices);
}

/**
* Strip the delimiter if it appears in the entered text.
* No substitution or warning is provided.
*/
P1: FCH/SPH P2: FCH/SPH QC: FCH/SPH T1: FCH
WY009-16 WY009-BenNatan-v1.cls May 11, 2004 14:50




320 Chapter 16

protected String stripDelimiter(String choice) {

int index = choice.indexOf(DELIMITER);
if (index == -1)
return choice;
return stripDelimiter(
choice.substring(0, index) + choice.substring(index + 1));
}
}


A Poll instance will be created by a call to the persistent store access
class. To simplify the persistence access for the answer choices they will
be stored as a single string. When the choices ¬eld is updated, the setter
method will also parse the string and update the list of choices that are held
in the choiceList ¬eld as well as update the numberOfChoices ¬eld.
This will be important when we de¬ne the persistence class de¬nitions in
the next section.
There will also be a method to initialize the poll results. This method
will get the vote count for each answer choice from the persistent store and
calculate the voting totals and the voting percentages.



Implementing Persistence Classes
There will be two implementations for persistence layers for this portlet.
We will implement a database broker and a memory broker. Of course, the
data “stored” in memory is lost when the server restarts. But, it is useful for
demonstration purposes. Both broker types will extend the abstract broker
that we will de¬ne.
The Broker class de¬nes the following abstract methods:

getPoll(String pollName). Gets the poll information from the
datastore for the poll of the given name. Creates and returns a Poll
instance with that data.
getPollNames(). Returns a list of the names of existing polls.
deletePoll(String pollName). Deletes the poll data with the
given name.
updatePoll(PollBean poll). Updates the poll data.
vote(String userid, String pollName, int choiceIndex).
Records a vote for the given user in the given poll for the choice index.
hasVotingStarted(String pollName). Returns
true if a vote has been registered for a poll name; false otherwise.
P1: FCH/SPH P2: FCH/SPH QC: FCH/SPH T1: FCH
WY009-16 WY009-BenNatan-v1.cls May 11, 2004 14:50




Portlet Development 321


hasUserVoted(String userid, String pollName). Returns
true if the userid has a recorded vote in the poll with the given name.
voteCount(String pollName, int choiceIndex). Returns the
number of votes for the given choice index for the poll with the given
name.
The Broker class has static methods and static variables to return an in-
stance of either a DbBroker or a MemoryBroker. The portlet con¬guration
de¬nes the persistent store type, memory, or database. If a type of database
is selected, then a datasource name is speci¬ed as well. A call to the Broker
getInstance() method will return either a DbBroker or MemoyBroker
instance based on those values.

DatabaseBroker
The DatabaseBroker queries the poll and vote data from two tables in
a database speci¬ed by the named datasource. The tables are POLL and
VOTE and can be de¬ned by the following SQL:
CREATE TABLE POLL (NAME VARCHAR(32) NOT NULL, QUESTION VARCHAR(256),
CHOICES VARCHAR(512), PRIMARY KEY(NAME))

CREATE TABLE VOTE (USERID VARCHAR(255) NOT NULL, POLL VARCHAR(32) NOT
NULL , VOTE INTEGER NOT NULL, PRIMARY KEY(USERID, POLL))




Implementing Utility Classes
Our portlet de¬nes two exception classes. One is an exception to wrap
another thrown exception and associate our own message with it. The other
is a message exception that we can use to terminate processing and put a
message out to the portlet page. These are PollWrapperException and
PollMessageException. Both extend PollException.
Finally, the string constants needed for the portlet application are de¬ned
in the PollConstants interface. This completes the utility classes in use
by the Poll portlet.


Summary
In this chapter you looked at the key elements of the code for the Poll Portlet
implemented using the IBM Portlet API. We discussed the overall design
of the portlet application and focused on a design that maintained good
separation of concerns.
P1: FCH/SPH P2: FCH/SPH QC: FCH/SPH T1: FCH
WY009-16 WY009-BenNatan-v1.cls May 11, 2004 14:50




322 Chapter 16


The portlet implementation should be in the use of PortletSettings
and PortletData for con¬guration and customization data. We dis-
cussed issues of page navigation. The portlet demonstrated an imple-
mentation with multiple portlet modes. We accessed text strings from
ResourceBundles in the java code as well as the JSP to enable the portlet
for internationalization. We showed the use of the PortletLog to generate
trace-logging messages. We implemented two Broker classes to manage a
persistent store for our poll data.
In the next chapter you will ¬ll in any missing pieces of this implemen-
tation from the download source code. We will execute the code using
WebSphere Studio™s test environment.
P1: FCH/SPH P2: FCH/SPH QC: FCH/SPH T1: FCH
WY009-17 WY009-BenNatan-v1.cls May 11, 2004 14:51




CHAPTER

17
Portlet Interactive Debug
and JSR 168 Example

This chapter will examine the interactive test environment of WebSphere
Studio. You will execute the example Poll portlet discussed in the last chap-
ter. You will learn about con¬guring the test server and how to use the
debugging environment using a local Portal test environment.
You will also modify the example Poll portlet to use the JSR 168 API
instead of the IBM Portlet API used in its initial development.



Poll Portlet Project
If you did not work through the complete portlet implementation in the last
chapter you may want to download the source code and import it into an
empty portlet project, allowing the import to overwrite any existing ¬les.
You can also use the import utility to create a new project. After the import
is complete and the project is created, you will see a number of errors in the
project. That is because required portlet jar ¬les are not on the project build
path. As we have discussed, one of the bene¬ts of using the portlet toolkit
to create portlet application projects is that it will set up the correct class
path de¬nition.
To add the needed IBM Portlet API jar ¬les to the project build class path,
open the properties on the newly created project by right-clicking on the
project in the Navigator pane and selecting Properties from the pop-up
menu. Select Java Build Path and then the Libraries tab. You can add the
required jar ¬les with the following steps:



323
P1: FCH/SPH P2: FCH/SPH QC: FCH/SPH T1: FCH
WY009-17 WY009-BenNatan-v1.cls May 11, 2004 14:51




324 Chapter 17


Select Add Variable, then select WPS V5 PLUGINDIR in the New
Variable Classpath Entry and click Extend. Select portlet-api
.jar and click OK.
Select Add Variable, then select WPS V5 PLUGINDIR in the New
Variable Classpath Entry and click Extend. Select wps.jar and click
OK.
Select Add Variable, then select WPS V5 PLUGINDIR in the New
Variable Classpath Entry and click Extend. Select wpsportlets
.jar and click OK.
Select Add Variable, then select WAS 50 PLUGINDIR in the New
Variable Classpath Entry and click Extend. Expand the lib directory
and then select dynacache.jar and click OK.
Click OK to exit properties and save changes.

You may need to rebuild the project to resolve some JSP errors. Right-click
onthe project in the Navigator pane and select Rebuild Project.



Portal Server Con¬guration
You can use Studio to debug portlet applications that are running on Web-
Sphere Portal running locally within the Studio environment or on a re-
mote machine. In this chapter we will discuss local environment debugging,
which is referred to as WebSphere Portal 5.0 Test Environment. You will need
to ensure that you have installed WebSphere Portal in WebSphere Studio
using the Portal Toolkit installer.
In order to run the portlet in the local portal test environment, you must
create a server and portal server con¬guration in Studio (see Figure 17-1).
After the portal server con¬guration is de¬ned, you can publish and debug
your portlet application.
In Studio, select File ➪ New ➪ Other from the menu bar. In the dialog
box that opens, select Server in the left pane and then Server and Server
Con¬guration on the right. Select Next.
In the next dialog box, enter a name of your choice for the server and
select Test Environment under WebSphere Portal version 5.0 for the Server
type. Click Next.
The next dialog box allows you to change the HTTP port number that
will be used in the server con¬guration (see Figure 17-2). Make a change
if needed and then click Finish. Change to the Server perspective. You will
see the server you just created in the Server view. Open the server to edit
the con¬guration.
P1: FCH/SPH P2: FCH/SPH QC: FCH/SPH T1: FCH
WY009-17 WY009-BenNatan-v1.cls May 11, 2004 14:51




Portlet Interactive Debug and JSR 168 Example 325




Figure 17-1 Creating a new server in Studio.


Here you can specify the data source for the poll application if you will use
a database for storing the application data. First, select the Security tab to
open the Security Options page. Create a JAAS Authentication Entry for the
userid that will be used to authenticate to the database when a connection
is requested. Then select the DataSource tab. From the Data Sources page
create a JDBC Provider, if needed. For DB2, select IBM DB2 Database Type
and DB2 Legacy CLI-Based Type 2 JDBC Driver for the JDBC provider type.
On the second page make sure the class path is set to point to the correct
JDBC driver library.
Select the JDBC Provider and click Add to add a data source. From the
Create a Data Source dialog box, select the JDBC Provider and select Version

<<

. 54
( 87 .)



>>