Tài liệu XML, XSLT, Java, and JSP: A Case Study in Developing a Web Application- P4 - Pdf 87

132
Chapter 6 bonForum Chat Application: Implementation
Using Xalan-Java 2 Instead of Xalan-Java 1
The bonForum release with this book was developed before a stable release of Xalan-
Java 2 was available. It turned out that the part of Xalan that we use (XSLT transfor-
mation) was among the most reworked parts of the Xalan product as it went to
version 2. Here is what the version 2 readme.html says:
Given the scope of the redesign, the changes with respect to Xalan-Java 1.x are
global in nature …. Xalan-Java 2 implements the TraX (Transformation API for
XML) interfaces.The product of extensive open-source collaboration by mem-
bers of the XML developer community,TrAX provides a conceptual framework
and a standard API for performing XML transformations.
Fortunately, the changeover to Xalan-Java 2 did not have a major impact on the design
of bonForum—it requires only a somewhat different way to create and use an XSLT
processor—so the input and output of that processor will remain the same. For infor-
mation about using either Xalan Java 1 or 2 with the bonForum project, please refer
to Chapter 4, “XML and XSLT: Xerces and Xalan,” Section 4.5, “Installing Xalan.”
Also, check for the latest bonForum information at
www.bonForum.org
.
Xalan’s XSLT Servlet
At the time we were developing our XSLT custom tag, there was no XSLT servlet in
Xalan.Today, we may be tempted to solve the XSLT requirements of our JSP tag by
having it access the XSLT servlet that is now provided with Xalan.We recommend
that you try that approach in similar situations.We tried again, with Xalan 2.0.0, but it
still had the old documentation for the Xalan-Java 1.2.2 servlet, although it has
changed drastically, including the name of the servlet. Now, with Xalan 2.0.1, the
servlet sample is a very useful resource. Relative to the root folder for either Xalan-
Java 1 or Xalan-Java 2, look for the XSLT servlet documentation at
/docs/samples.html#servlet
.

outDoc=”..\\webapps\\bonForum\\mldocs\\foo.html” >
</bon:transform>
Actually, the type value shown is a rather late addition.We now use type attribute val-
ues to select XSLT processes. Current acceptable values are “Xalan Java 1” and “Xalan
Java 2”.There is also a session attribute called “xalanVersion” which can be set to any
acceptable value for the type attribute. One way you can set that session attribute is by
including something like the following HTML form (JSP or otherwise) that is
POSTED to the BonForumEngine:
<form name=”forum_entry” method=”POST” action=”/bonForum/servlet/BonForumEngine”>
<label for=”xalanVersion”>
Apache Xalan Version?
</label>
<input id=”xalan1” type=”radio” name=”xalanVersion” value=”Xalan-Java 1”>
Xalan-Java 1
</input>
<input id=”xalan2” type=”radio” name=”xalanVersion” value=”Xalan-Java 2” CHECKED>
Xalan-Java 2
</input>
<input type=”hidden” name=”actorReturning” value=”yes”>
</input>
<input type=”hidden” name=”bonCommand” value=”visitor_executes_choice”>
</input>
<input type=”submit” value=”continue” name=”submit”>
</input>
</form>
The BonForumEngine servlet will set the session attribute from the request parameter.
The tag class will get and use that session attribute if a value of
xalanVersion
is used
for the type attribute in the custom tag on the JSP. Do not worry if the details are not

<bon:transform
type=”bonTransform”
inDoc=” bonForumXML “
styleSheet=”..\\webapps\\bonForum\\mldocs\\identity.xsl”
outDoc=”outputNormalized” >
<%=output%>
</bon:transform>
6.1.15 Style Sheets
When we had
TransformTag
working, we were able to use some XSL style sheets to
accomplish some of our XML data-display goals. Eventually, as the prototype is further
developed, we expect that there will be many more style sheets.The ones that we have
used already are discussed in Chapter 10.
All the style sheets that we used in the book version of bonForum were applied
using XSLT to the entire contents of the bonForumXML
ForestHashtable
. In the
future, we plan to have a more selective mechanism for determining the XML
InputSource
for the XSLT process. For that reason, we have already included in the
project a second
ForestHashtable
object, named
bonBufferXML
. It will help when we
want to apply XSLT to only a selected subset of the entire data contents of
bonForum.
The XSL style sheet files are all found in the folder TOMCAT_HOME\webapps\
bonForum\mldocs.

request (from the same browser session) is being serviced, the
BonForumEngine
servlet
copies it to a session attribute that it creates with the same name as the request para-
meter. Here is an example, from BonForumEngine.java:
chatTopic = normalize((String)request.getParameter(“chatTopic”));
if(chatTopic.trim().length() > 0) {
session.setAttribute(“chatTopic”, chatTopic);
}
In case you are wondering what the
normalize
method does, it serves two purposes. It
makes sure that strings input by the users can be legally included in the XML data, by
substituting inadmissible characters with the appropriate character entities. It also
replaces null values with empty strings so that we do not later have to add code to
check for null values. Nor do we have to handle null-value exceptions commonly
caused by passing null string values to Java methods that expect a string.
One session attribute in the application is called
bonForumStore
. It enables us to
find the application interface to its XML database from anywhere, including JSP, that
can access the session object with this attribute.
The use of session attributes to store information has important features and conse-
quences that must be grasped to understand the Web application implementation:
n
Each user is provided a separate variable context in the Web application.
n
Each user context is tied to the existence and duration of one session, which
connects all the requests made by one browser for a configurable period of
activity.

each user, and there must be some way to know what belongs to whom.
Of course, this kind of problem is not at all new.There are obvious solutions using
relational database tables. On the other hand, if we were using an XML document
only to store data, the solution would most likely involve the use of XPATH.
However, bonForum stores XML documents in a special
hashtable
class,
ForestHashtable
, which is a simulation for a relational database table design. Each ele-
ment node of the XML is stored in a table row with a key called a
NodeKey
, which
encodes the position of the node in a tree structure.We had to find our own solution
to the problem of relating data to the bonForum users.
Let’s use an example here. A user of the bonForum is associated with at particular
chat.That chat is represented by an element node in the XML data.We could associate
the user with the chat by adding a child element inside the chat element.That child
element would either represent the user or point to an element elsewhere that repre-
sents the user (we did the latter).
We wanted to avoid repeated searches through our data every time the same piece
of information was required.There were many places in the code where we needed to
know which chat element belonged to the current user. If every time we needed that
answer we had to search through all the data looking for the chat element that con-
tained a child that was associated with that user, it was time to find a better way.
First, we made a rule.Whenever possible, we defined elements in our XML so that
they would be unique for each user.That meant that they would be unique within an
HTTP session. One session can “own” only one chat element. One session can own
only one guest element.
The second thing we did was to create another hashtable, called a
NodeNameHashtable

NodeKey
of the node we need.This involves yet another hashtable, this time one
called
PathNameHashtable
. In this case,
NodeKey
s are stored in the
hashtable
using keys
that indicate the path to a subject element in the XML data tree.
As noted elsewhere, we have constrained the possible names that these elements can
have. Duplicate sibling-node names are not allowed.Thus, we have a unique set of
subject pathnames.When a user chooses a chat to join, the choice is associated with a
unique pathname.This pathname can then be used to quickly retrieve the subject ele-
ment required for the user to join the chat.
6.1.18 Synchronizing Multiple Threads
We soon had to pay more attention to the question of how our Web application
would handle an environment in which it was being used by not one developer, but
by many clients. One of Java’s strengths is its built-in thread management.We hoped
that it could solve the problem of multiple, simultaneous access to our
BonForumEngine
Java servlet.
Again, we recommend to the reader the book Thinking in Java, by Bruce Eckels.
Especially helpful in the present context are Chapters 14 and 15: “Multiple Threads”
and “Distributed Computing.”That book is a good resource for learning about those
two topics.
Critical Resources
Essentially, we had to find a way to use the Java mechanism of synchronization to pro-
tect access to critical resources.We could synchronize access either to methods or to
blocks of code.A lot can be said about the topic of synchronization in Java by using

Java keyword.
At first, we thought that meant synchronizing all the public methods in
BonForumEngine
.These include methods that are capable of changing the
bonForumXML
object. However, if we did that, the lock being used would be on the Java servlet
object. It would not be much of a servlet if only one client can access it at a time, so
we knew that there must be a better way.
Instead, we synchronize any “critical code” sections on the
bonForumXML
instance. In
effect, this means that whoever owns the XML representation of bonForum can access
the methods that are capable of changing its contents. All the other users must wait
their turn; they are blocked—in effect, queued up and buffered—by the Java synchro-
nization mechanism.
Questions Regarding Synchronization
Certainly, the way that we have set up multiple thread access to the data is an area that
needs far more testing. For one thing, it is important to minimize the number and size
of synchronized code sections in the application because they constitute bottlenecks
and overhead.
We also want to make sure that there are no ways to defeat the protections offered
by the synchronization that we have added—for example, by accessing methods from
JSP.
Getting thread synchronization right is partly an art, and we will not be surprised if
problems surface. However, after we have implemented a persistent database table from
our
ForestHashtable
design, we will at least be able to recover from a thread clash,
which is not possible now!
6.2 Displaying and Selecting Chat Subjects

ment for its subject.
n
Each chat also has a short description added by the user who starts it.This
chatTopic
must also be stored, related, and retrieved.
This chapter is not the place to describe the solution that we devised. Indeed, the
solution involved working with all the various parts of our new Web application sys-
tem.Therefore, again, understanding what is going on in bonForum may require read-
ing relevant sections in several of the more technical chapter yet to come. Here we
simply list the book chapters and sections that will help you the most.You might want
to mark this list and refer back to it later!
n
Chapter 7: “JavaServer Pages:The Browseable User Interface”
n
Section 7.2.5: “visitor_starts_chat_frame.jsp”
n
Chapter 8: “Java Servlet in Charge: BonForumEngine”
n
Section 8.1.20: “The
processRequests()
Method: Handling Host
Executes Chat”
n
Section 8.2.12: “Invoking Chat Methods from JSP Custom Tags”
n
Chapter 10: “JSP Taglib and Custom Tag: ChoiceTag”
n
Chapter 11: “XML Data Storage Class: ForestHashtable”
n
Section 11.5.2: “

devised.Therefore, in this chapter we will try to discuss only the implementation
process itself. Here is a list of all the chapters and sections that will help you to under-
stand the process of displaying chat messages:
n
Chapter 7: “JavaServer Pages:The Browseable User Interface”
n
Section 7.2.9: “host_executes_chat.jsp”
n
Chapter 8: “Java Servlet in Charge: BonForumEngine”
n
Section 8.2.12: “Invoking Chat Methods from JSP Custom Tags”
n
Chapter 9: “Java Applet Plugged In:
BonForumRobot

n
Section 9.3: “
BonForumRobot

n
Chapter 11: “XML Data Storage Class:
ForestHashtable

n
Section 11.11: “Initializing the
bonForumXML
Database”
n
Section 11.12: “Runtime
bonForumXML

It seemed that the process of adding a
messageKey
element to a chat element was dif-
ferent from all other add operations. A guest must be allowed to add messages for any
chat joined, even if the guest has not added that chat’s element.
6.3.3 The Need to Refresh Chat Messages
When an actor adds a message to a chat, that message should be seen very soon by all
the other actors in the chat.We needed to find a technique to do this in our
bonForum.Without this, it could hardly be called a chat forum; it would be more like
a message board than a chat room.
Possible Refresh Mechanisms
We considered some mechanisms for refreshing the chat history display on the
browsers. Some of these were rejected for being too “client-side.”
We tried using a Pragma setting to cause a refresh of the page that had the chat
messages displayed on it.We got that working, but it had two problems for us. One
was that it was quite browser-dependent and would not work on all browsers.
Although that was not an immediate consideration because we were only testing with
IE5.X, we wanted our Web application eventually to be browser-independent.
The worse problem was that there was a lot of flickering in the message’s display. It
seems that when IE5 repainted the display, it first erased the old one to white.We
started looking for other uses of the refresh Pragma on Web sites and found some that
seemed to work. An occasional refresh is not bothersome, especially if you are not
always looking right at the frame that is being refreshed. In our case, we wanted one
refresh every 5 seconds, so the user would be staring at the flickering messages display
most of the time.That was quite bothersome.
06 1089-9 CH06 6/26/01 7:31 AM Page 141
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
142
Chapter 6 bonForum Chat Application: Implementation
6.3.4 BonForumRobot Java Applet to the Rescue

showing the document from the browser cache instead of from the server.We could
see messages that had been added from different browsers, but always the same ones.
We then tried some well-known techniques to prevent caching of the pages, but noth-
ing worked.The browser stubbornly refused to repeatedly request the JSP from the
server.
Again, we started to think that we would need even more client-side power to
solve this problem. However, we finally found a smaller trick that works.The
showDocument
method in the
BonForumRobot
applet refreshes the page using a different
JSP filename each time.We do that by concatenating the current time in milliseconds
with the real JSP filename to get unique names.We then add a new “fake” file exten-
sion (.tfe) that we have mapped in the Tomcat Server configuration file so that it is
sent to the
BonForumEngine
servlet.The servlet strips off the time and extension and
forwards the request to the correct JSP.
06 1089-9 CH06 6/26/01 7:31 AM Page 142
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
143
6.3 Displaying Chat Messages
The only problem we found with this was that the browser happily cached a page
every time a refresh occurred. After a while, the browser cache was full of copies of
essentially the same JSP document, such as the following series (this was before we
added frames):
http://localhost:8080/bonForum/guest_executes_chat.jsp960816479237.tfe
http://localhost:8080/bonForum/guest_executes_chat.jsp960816479247.tfe
http://localhost:8080/bonForum/guest_executes_chat.jsp960816479257.tfe
6.3.6 Testing of Web Application Begins

host_executes_chat bonCommand
, which caused the
firing of the host_executes_chat.jsp JSP document.
06 1089-9 CH06 6/26/01 7:31 AM Page 143
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
144
Chapter 6 bonForum Chat Application: Implementation
Because we added frames to the application, we use several JSP documents together
to create most of the forum states. One JSP page creates a frameset with two or three
frames in it. Another JSP creates the content of one of the frames, which usually dis-
plays information to the user. Another JSP fills a frame that displays user input fields
and controls.Yet another frame holds
BonForumRobot
in a
jsp:plugin
element.We will
discuss others later in this chapter.
So as not to lose track of our design, we came up with a naming convention that
retains the original JSP name for the document that creates the frameset.The other
JSP documents that help to create the same forum state use the same name with addi-
tional suffixes.
This is better seen from examples.The JSP files that display and refresh the chat
messages to a host and that allow the host to enter a new message are located in files
named as follows:
host_executes_chat.jsp
host_executes_chat_frame.jsp
host_executes_chat_controls.jsp
host_executes_chat_robot.jsp
After we introduced frames to one of our forum states, it was natural to put them into
most of the application. One of the main reasons for that was to achieve a consistent

host_executes_chat_console.jsp
host_executes_chat_ready.jsp
We do need to make things a bit prettier.We can put a cute image on the robot.We
can put some advertising space on the applet panel. Perhaps we can make the robot
into an animated agent-like creature.
6.3.9 The Scrollbar Reset Problem
At this point, the most important remaining problem was the fact that the list of chat
messages was scrolled back to the beginning after each refresh by the applet.The prac-
tical way to do this is with dynamic HTML, or other client-side solutions. Again, we
rejected these to explore server-side solutions to the problem.
In fact, not only did the select list scroll unpleasantly, but as soon as there were
more messages than the frame could display in the HTML select element, the frame
itself would get a second scrollbar of its own, and that made the display twice as ugly.
Still, it looked better now than it had without the frames.
Our solution for this problem turned out to be quite involved.The chat messages
are now output one page at a time, with the page size being selectable by the user.
Four buttons on the browser display, labeled First, Previous, Next, and Last, allow navi-
gation through all the messages in the chat history. Missing is a one-message-at-a-time
scrolling action, which will be added later.This solution needs more work.
The real work for all this happens in the method
bonOutputForumChatMessages
of
the
BonForumStore
class.You will probably have to refer to the source code for that
Java class to understand how that method works.There are also some relevant discus-
sions in Chapters 7, 8 and 10.
6.3.10 Filtering Chat Messages by Session
When we first got some chat messages to display, we were getting all the messages in
bonForum, not just the ones in the same chat as the user getting the display. Although

One problem that had not been foreseen provided somewhat of an implementation
challenge. Our plan called for elements to be “attached” to the HTTP session that cre-
ated them, as a way of providing user scope, albeit of short duration. The problem was
that for a user to join a chat as a guest, its thread had to first find the chat.The chat
was not attached to the session of the would-be guest. Rather, the chat was attached
to the session of the host that created it.
The way we solved that problem is perhaps not immediately obvious. Although
much is said about it in code comments and in the chapters to come, it will help to
have an overview here as well. It might be that the overview is confusing without the
details, and the details are confusing without the overview. If you are a software devel-
oper, you are probably accustomed to that kind of situation by now.You might want
to just fold the corner of the page (unless you are reading it in the bookstore) and
move on to the next book section (in this book, not the store!).
When a visitor chooses a chat to join, the selection includes both a chat subject
and a chat topic.The chat subject gives the complete path to the correct chat subject
element in the XML database. Each chat that exists for that subject is represented by a
child element of that subject element.That child element has as its name the session
ID value related to the host that created that chat. An attribute of the child element is
set to the chat topic added by the chat host.
We can find the chat subject element from the would-be guest’s choice by using
pathNameHashtable
. By iterating its children, searching for the one with the correct
chat topic, we locate the element whose name gives us the session ID of the chat host.
That enables us to find the chat element using
nodeNameHashtable
, which solves the
problem.The user’s thread can now add a
guestKey
to the chat element, transforming
the user from a visitor to a guest.

to brand messages and to display messages.
Whenever a message is sent to a chat by either a host or a guest, it is associated
with the
itemKey
of the chat, which is unique in bonForum. Because that same
itemKey
is stored as an attribute of the chat element, a relationship is formed between
all the message elements and the chat to which they belong.The
outputChatMessages()
method can then use this relationship to find the messages that
it outputs (although, as we mentioned, that is probably not the best way to do that).
6.4.2 New XML Methods
Solving the problems that we just discussed gave us good chances to develop our
XML data functionality further.We added methods to get attribute values and to find
a child element with a given attribute value.We also added a method to edit a
BonNode
in a
ForestHashtable
(such as
bonForumXML
). Rather than creating an object that
understands the entire official XML recommendation, we would rather let necessity
dictate the evolution of the object.
If you want to see more details about finding the chat element, you can look in the
source code. First, look in the file BonForumEngine.java. Look for all the code that
uses term
chatItem
and the context of that code.Then look in the file
ForestHashtable.java. Look at the code for these two methods:
subjectNodeKeyFromPathName

ForestHashtable
) as a string.
Now we decided to make it the input XML stream for the Xalan XSLT processor as
part of our
TransformTag
class.
Displaying the available chats would mean showing both the chat subject and the
chat topic.We began with the following vague idea:We would create a style sheet that
would find each chat subject item. It would accumulate the path to each such element
in a variable.Then it would append the chat topic attribute to that subject path, and
output that.
6.5.1 Including XSLT Output on JSP Output
As we discussed in Section 6.1.13, “Including Documents in a JSP,” we had grabbed
the wrong JSP
include
to display the output of the
TransformTag
prototype. Before
we found our mistake (and after we had started using XML output from the XSLT
processor instead of HTML), we came up with a different solution using a JSP script-
let and a JSP expression.That is a great thing about JSP development: It is rich in pos-
sibilities. Even if one of the main reasons JSP was developed was to separate the roles
of page designers and code developers, there are times when scriptlets are very handy
for getting things working. Here is the code, which should really have used a
StringBuffer
:
<%
String selectChatGuests = “”;
String optionChatGuest = “”;
DataInputStream in = new DataInputStream(

Rem xalanTest.bat:
java org.apache.xalan.xslt.Process -IN test.xml -XSL bonChatItems.xsl -OUT
bonChatItems.xml
type bonChatItems.xml
Note that if you are using Xalan Java 2, you will have to update the command in this
batch file.You can find information about that by reading the Xalan command line
page of the Xalan 2.0.1 docs. Assuming the usual drive and installation folder, browse
the following document: C:\xalan-j_2_0_1\docs\commandline.html.
The file, called test.xml, contained fake
bonForumXML
data that included just enough
to test the XSLT processing. In the actual bonForum project, the XML input data for
the transforms come from the
bonForumXML
. All this is described in Chapter 10, so
there is no need to elaborate here.
Our XSLT solution could use some improvement. In accordance with our experi-
mental agenda, we pressed on as soon as a minimally acceptable result was obtained.
Getting a full system up and running is a higher priority than taking care of the details.
Successful Display of Available Chats
The details about displaying available chats are covered in Section 7.2.13,
“visitor_joins_chat_frame.jsp,” in Chapter 7.The output of the XSLT process now
does not need to go to a file and then be read back into the page output, as in our
prototype. Now we can output it to a scripting variable named
output
, which we can
display within the
TransformTag
element. (You can read about the
TagExtraInfo

element to access the method
bonForumXML.editBonNode
in the
BonForumStore
class.
We use that, along with lots of other gnarly-looking methods in the
BonForumStore
and
ForestHashtable
classes, to change the value of the
rating
attribute of the guest
chosen by the host actor.
6.6.2 Displaying a Guest List to Guests
A technique similar to that used to display the guests in a chat to a host executing a
command should be used again to show the guest list to each guest.That is, indeed, an
expected feature of a chat room.
6.7 Outputting the bonForum Data as XML
It is useful to have the bonForum data in the form of an XML stream.This can be
done two ways in the prototype version of bonForum. Eventually, this will be some-
thing that can be done by the system actor. At present, that actor does nothing.
Because these files provide overviews of the project useful for design, study, and
debugging, we will show the JSP code here in this chapter.The first example provides
06 1089-9 CH06 6/26/01 7:31 AM Page 150
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.
151
6.8 Future of bonForum Project
a file that is a literal version of the simple XML contents of the
bonForumXML
ForestHashtable

done right. Certainly, although writing a book about developing code might have its
own benefits for a project, it also takes time away from the development process. It has
often been necessary to omit some necessary features or leave in some annoying prob-
lems so that we can complete the book.The items in this section remain high on our
list of priorities—and should for anyone joining the open source BonForum project
on SourceForge (

).
6.8.1 System Actor Functionality
From the beginning, a System actor has been planned that would function as a higher
authority in bonForum.This actor would have access to all the commands and states
of bonForum, plus some of its own supervisory states that would enable tuning,
troubleshooting, and regulating the Web application.
06 1089-9 CH06 6/26/01 7:31 AM Page 151
Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark.


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status