Instant Help for WebCT @ CSULA

fawnhobbiesSoftware and s/w Development

Jul 4, 2012 (5 years and 4 months ago)

450 views

Instant Help for WebCT @ CSULA
for the eLearning Programs and Support Center
by Nicholas Mew
Spring 2006
Instant Help for WebCT @ CSULA
Project Report
Nicholas Mew
June 6
th
2006
1.
Abstract
Imagine you are taking an online course at CSULA using WebCT. You do not have a

technical background, and whats more, you are not familiar with WebCT. Over the first few

weeks, the course seems to be going fairly well, and you have no problems accessing the

professors notes. This is of course until the midterm paper, worth 50% of your final grade, is

due. You have completed the paper, but for some reason, you can't figure out how to submit it to

the professor! The assignment is now due in 30 minutes, and your going to fail the course

because you can't figure out how to use WebCT's assignment drop box. As you franticly search

CSULA's WebCT home page for a solution, you come across a link directing you to instant help

for students using WebCT. The link opens up a window, and you are immediately helped by a

CSULA WebCT administrator. The administrator guides you through the process of uploading

and submitting an assignment through the WebCT assignment drop box, and your problem is

solved. You get an A on the paper, and ace the course. Chat Help for WebCT @ CSULA is the

solution for many CSULA students' technical issues with WebCT.
The application will help

many CSULA students get their mind off the technology and back on to their course.
2.
Introduction
WebCT is an online tool for learning, that has been purchased by CSULA for all of its

fully online, and partially online, hybrid, courses. Hundreds of classes are taught every quarter

using WebCT, and thousands of students take these courses every quarter. Although the campus

supplies adequate help for faculty that want to create courses for WebCT, currently, the only way

for students to get technical help with WebCT, is to fill out an online form which typically gets

answe
red after one or two business days. This provides a particularly inefficient service for

students who have time sensitive questions that need immediate attention because of assignment

due dates and limited times of availability for quizzes and tests. The WebCT administrators on

campus are located in the eLearning Programs and Support (eLPS) lab. The lab only caters to

faculty, so students cant even talk to someone face to face. In search of a better system to provide

technical assistance to students, the eLPS lab proposed an application that would allow students

to get live help from WebCT administrators when the eLPS lab is open.
The solution we propose, Chat Help for WebCT @ CSULA, allows just this. It is an

instant messaging application using Flash and Java technologies that allows students to click on a

link and get immediate technical assistance from a WebCT administrator at the eLPS lab. It will

solve the current problem of long waiting times for students who need technical assistance, while

still utilizing the staff at the eLPS lab as WebCT administrators.
Currently, this form is the only way students can get technical assistance for WebCT.
3.
Technical Background
3.1
Java 2 Platform, Enterprise Edition
The Java 2 Platform, Enterprise Edition (J2EE) is a set of coordinated specifications and

practices that together enable solutions for developing, deploying, and managing multi-tier

server-centric applications. Building on the Java 2 Platform, Standard Edition (J2SE), the J2EE

platform adds the capabilities necessary to provide a complete, stable, secure, and fast Java

platform to the enterprise level. It provides value by significantly reducing the cost and

complexity of developing and deploying multi-tier solutions, resulting in services that can be

rapidly deployed and easily enhanced. [1
] We used J2EE for the back end of the application.

Servlets, written in the Java programing language, were used to serve xml pages to the client

applications.
3.2
Jakarta Tomcat
Apache Tomcat is the servlet container that is used in the official Reference

Implementation for the Java Servlet and JavaServer Pages technologies. [2]
3.3
Java Programming Language
The Java programming language lets you write powerful, enterprise-worthy programs

that run in the browser, from the desktop, on a server, or on a consumer device. Java programs

are run on -- interpreted by -- another program called the Java Virtual Machine (Java VM).

Rather than running directly on the native operating system, the program is interpreted by the

Java VM for the native operating system. [3]
3.4
Flash Technology
Composed of Macromedia Flash and the Flash Player, Flash Technology is used to

create multimedia that can be run on a browser or from the desktop. Macromedia Flash is the

integrated development environment for Flash files that are then run on the Flash Player Virtual

Machine.
Flash technology has become a popular method for adding animation and interactivity

to web pages. Flash is commonly used to create advertisements, to add video to web sites and, to

develop Rich Internet Applications.[4] We used Macromedia Flash to compile the ActionScript,

and develop and build the client side applications.
3.5
ActionScript 2.0
ActionScript is the scripting language for Macromedia Flash. ActionScript 2.0, the latest

version of the ActionScript language is an object-oriented programming language that supports

full class inheritance and all the features that developers demand from a mature language. It

gives you a more flexible programming environment and superior debugging abilities.
[5] We

used ActionScript to develop the client side applications. Some ActionScript was written within

the Flash IDE while some was written separately and later compiled using the Flash IDE.
3.6
Extensible Markup Language (XML)
Extensible Markup Language (XML) is a simple, very flexible text format which like

HTML, derived from SGML (ISO 8879). Originally designed to meet the challenges of large-
scale electronic publishing, XML is also playing an increasingly important role in the exchange

of a wide variety of data on the Web and elsewhere.[6] We used XML to pass data between our

backend, business tier, and our front end applications. The use of XML in this manner allows the

applications front end to change if necessary. It can be implemented with any technology that

can parse XML and send Http requests.
4. System Overview
Chat Help for WebCT @ CSULA is an instant messaging application accessible over

Http. The application consists of a server that keeps track of all chat sessions, all the data

necessary within those chat sessions, including the messages themselves and the administrator

and user names. Aside from keeping track of this data, the backend application also generates

data in XML format for the client applications. The client applications then take the data in the

XML document and present it in an intuitive and easy manner for the user. Three client side

applications consist of an administrative application to see new users coming in to the system,

and two instant messaging applications. One for students that is accessible over the Internet, and

another for administrators that is a standalone Flash projector program. Because Chat Help for

WebCT @ CSULA is accessible over Http, which is not blocked by firewalls that allow Internet

access, it is accessible by anyone who is already accessing WebCT.
User Instant
Messaging App.
XMLgenerator
Servlet
Chat Manager
Class
Chat Class
Message Class
Admin Instant
Messaging App.
Administrative
Application
Figure 1
4.
Design and Implementation
4.1 GUI Design
The GUI design is simple and intuitive in all three client applications. Each application

has a step by step procedure, and users are only allowed to make a certain decisions at each step.

This design prevents the user from being overwhelmed and allows for the most efficient use

possible.
Student Client Application
The student GUI has two steps. Once the user has clicked on the link to open the

application, the user is prompted to input their name, and their initial question. The user cannot

continue unless they have input text in both fields. Once the fields are filled the user can either

click a button labeled chat or hit the enter key to continue. The form quickly slides off to the left

revealing a large text box that displays a message to wait for an administrator to enter the chat.

Below this text box, there is another input text box, and two buttons, one labeled send, and the

other labeled exit. The user only has these two choices. When the administrator enters the chat,

the user is notified, and can begin communicating with the administrator by entering text in the

bottom text field and hitting enter or clicking on the send button. The users messages are labeled

with his/her name in green, and the administrators messages are labeled with his/her name and

labeled in blue. After the users' question has been answered, they click the exit button, and the

window closes.
To implement this design, we used several frames in flash. The first frame displays the

two input fields. We add some ActionScript to the button so that when it is released, it checks if

the two input fields have been filled, and if they are, then it can continue on to the next frame.

The next frame contains the animation that moves the form to the left revealing the chat fields

underneath. The animation stops when we reach the frame containing the ActionScript for the

chat. In this frame, the larger text box that displays the messages is filled with the users name

and initial question. A third message is added telling the user to wait for an administrator to enter

the chat session. This frame also contains an ActionScript method that queries our server for new

messages for this particular chat. Any new messaged are displayed in the text box, and a simple

check for who sent the message defines what color the senders label should be.
Administrative Application
The administrative GUI is also minimal in design to allow a simplified system that can

control the entire application. This application also has two significant steps. When the

administrator first opens the application, they are presented with a field to enter their name, and

either a button that allows them to open the chat system, or to simply enter the chat application

depending on weather or not the chat system is already open. Once the administrator clicks either

button, the button disappears, and the text field moves to the top corner of the window, and fades

to black, leaving only white text with a black background. A close chat button appears, and two

scrolling buttons appear at the top and bottom of the window. Placing the mouse over the scroll

up and down buttons moves the list of buttons up or down respectively. Between these two

buttons appear the chat buttons. Each chat button represents a student that has entered the chat

application, and is waiting to be helped. Each one of these buttons also displays the students

name, and their initial question. If the administrator wants to select one of these questions, they

simply click on the button. The button disappears from the administrator application, and an

administrator chat window is opened. If the administrator wants to delete one of the chats, for

example if they have already answered the students question, they can click on a red close button

that appears on the top right of each chat button to delete the chat.
To implement this administrative application, several frames in Flash were used. The first

a blank frame, contains the ActionScript to query the server to check if it is open or closed.

Based on the XML formated data received, the application then either displays the open chat or

enter chat window. The buttons onRelease functions check to make sure the Administrator name

fields are filled, the open button will send a message to the server to open the chat and goes on to

the next frame, while the enter button simply goes on to the next frame. The next frame contains

the animations that bring us to the final frame of the application. This frame contains a static text

field that contains the label “Admin”, and another dynamic text field has been set to the

administrators name. A close button whose onRelease function sends a message to the server to

close the chat is displayed underneath.
The chat buttons are created whenever the application queries the server for available

chats. These chat buttons are put in a movie clip called “QuestionList”. The function to query the

server is repeated every 8 seconds, and each time, all the button movie clips are deleted and new

ones are created based on the servers response. Since it is possible that an administrator clicks on

a chat that has already been deleted, when the button is clicked, the servers response to an

already deleted, or unavailable chat is checked before the chat window is opened. If the chat is

not available anymore, the list is refreshed, and the button gets deleted. This is important since

several administrators will have this application open on their respective machines.
The function to scroll the buttons is inside the onEnterFrame function. This allows

smooth scrolling as opposed to having to click the button several times to scroll. If the

administrators mouse is in the buttons dimensions, the QuestionList movie will move up or down

5 pixels. The onEnterFrame function is called several times based on the frame rate of the movie,

in this case, 25 frames per second, making the scrolling of the buttons fairly smooth. The

function also checks that the maximum amount of chat buttons are visible at all times, which

means checking that the bottom of the QuestionList movie clip is never above a the bottom

scroll button, and the top of it is never below the top scroll button.
The onRelease function of the close chat button that sits at the top right corner of each

select chat button, sends a message to the server to end that particular chat. If the chat no longer

exists, or is unavailable to delete, the server will do nothing, the list of available chats will be

refreshed, and the button will disappear. If the chat is available to be deleted, the server will

delete it, and the button will disappear when the list of available chats is refreshed.
To implement the actions and look of the chat questions, a
Question
movie clip was

created with two dynamic text fields. One for the users name, and one for their initial question.

To make these buttons dynamic, the movie clip is bound to an ActionScript file called

Question.as, which defines the Question class. The class contains variables for the users name,

their initial question, the chat ID, and the two buttons, to select a chat and delete a chat. When

the application receives the list of available chats from the server, the button movie clip which is

bound to the
Question
class is created, and these variables are given the appropriate values.
Administrator Chat Application
The administrator chat application is executed when, in the administrative application, a

chat button is clicked. The chat application displays the users name, and their initial question.

The GUI is identical to that of the students application in its final frame. The simple design with

minimal options provides intuitive use and quick responses to students. A send button can be

used to send the text in the bottom text box to the student, and an exit button sends a message to

the server to give the administrator a null value for this chat, and then closes the window.
The administrative application executes this chat application by making use of the

fscommand
action
which takes two parameters,
command
and
parameters
. Fscommand
allows

the Flash movie to communicate with either the Flash Player, or the program hosting the Flash

Player, such as a Web browser. You can also use the
fscommand
action to pass messages to

Macromedia Director, or to Visual Basic, Visual C++, and other programs that can host ActiveX

controls.
[6
http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary
] In this

case, we used “exec” as the command, and the name of file to execute as the parameter. The file

to be executed must be in a folder called “fscommand” that is in the same directory as the

projector file that is calling it.
Like the student application, the administrator chat application queries the server for new

messages, and displays the messages in the upper text box. The implementation of this

functionality is identical to that of the student application. However, the exit button for this

application however has a different implementation. When clicked, a message is sent to the

server letting it know that the administrator is leaving, and the fscommand action is called again.

This time, the fscommand command is “quit” and the parameter is left blank. This closes the

applications window.
5 System Evaluation
The testing of this application has been done on a
Dell Optiplex GX270 Workstation

running on an Intel Pentium 4 2.8 GHz Processor with
512 MB of ram
setup with tomcat as a

server. We tested the server and application by creating 20 chats, each querying the server every

2 seconds for new messages. Unfortunately we have not been able to test the limitations of the

application. There was no slowdown or lagging however from the 20 chats querying the server

simultaneously, and the application had no errors in the process.
6 Conclusion and Future Work
Future additions to the application include adding the functionality to save chats to a

database, and displaying this data on a browser. To accomplish this, we plan on using servlets or

JSP's, hibernate, and for the mean time, an access database, since that is the database that is

currently used on the server. This project is a good example of a rich Internet application, and

will be a great asset to CSULA students using WebCT.
7 References
[1]
Java EE At a Glance. Sun Microsystems. 25 May 2006
<
http://java.sun.com/javaee/>
[2]
Apache Tomcat. Apache Software Foundation. 25 May 2006
<

http://tomcat.apache.org/

>

[3]
Java Technology Overview. Sun Microsystems. 25 May 2006
<
http://java.sun.com/overview.html>
[4]
Macromedia Flash. Wikepedia. 25 May 2006
<
http://en.wikipedia.org/wiki/Macromedia_Flash>
[5]
Flash MX 2004 ActionScript Learning Guide: Overview. Adobe. 4 June 2006
<
http://www.adobe.com/devnet/flash/actionscript/actionscript.html
>
[6]
Extensible Markup Language (XML). W3C. 25 May 2006
<
http://www.w3.org/XML/
>
StudentClientSource.as 6/6/2006
//Student Client Frame 1
/*****************************************************************************
***********************/
/*****************************************************************************
***********************/
/*****************************************************************************
***********************/
//stops animation from continuing to next frame
stop
()
;
//sets tab index of the text fields
userIDField_txt
.
tabIndex
=
1
;
questionField_txt
.
tabIndex
=
2
;
newChat
.
tabIndex
=
3
;
//sets variable chatID at root level
_global
.
chatID
;
_global
.
question
;
_global
.
userName
;
_global
.
chatFound
=
false
;
var
savedID
:
SharedObject
=
SharedObject
.
getLocal
(
"chatID"
)
;
//savedID.clear();
var
chatCheck_xml
:
XML
=
new
XML
()
;
//Very Important!!!!!
chatCheck_xml
.
ignoreWhite
=
true
;
/*************************************************************************/
if
(
savedID
.
data
.
chatID
!
=
undefined
)
{
//_level0.tester_txt.text
=
_level0.tester_txt.text
+
"found
flash
kookie...\n
chatID:
"+savedID.data.chatID+"\n";
link
=
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
checkChat&chatID="
+
savedID
.
data
.
chatID
;
//_level0.tester_txt.text
=
_level0.tester_txt.text
+
"link:
"+link+"\n";
_level0
.
chatCheck_xml
.
load
(
link
)
;
}
else
{
//_level0.tester_txt.text
=
_level0.tester_txt.text
+
"didnt
find
falsh
kookie.\n";
keyListener
=
new
Object
()
;
keyListener
.
onKeyDown
=
function
()
{
if
(
Key
.
isDown
(
Key
.
ENTER
))
{
_root
.
newChat
.
onRelease
()
;
}
}
;
Key
.
addListener
(
keyListener
)
;
}
/*************************************************************************/
chatCheck_xml
.
onLoad
=
function
(
success
)
{
//_level0.tester_txt.text
=
_level0.tester_txt.text
+
"xml.onLoad...\n";
if
(
success
)
{
//_level0.tester_txt.text
=
_level0.tester_txt.text
+
"loading
xml
(success)...\n";
if
(
_level0
.
chatCheck_xml
.
firstChild
.
firstChild
.
firstChild
.
nodeValue
=
=
"true"
)
{
trace
(
savedID
.
data
.
chatID
)
;
//_level0.tester_txt.text
=
_level0.tester_txt.text
+
"chat
"+savedID.data.chatID+"
exists:
\n"+_level0.chatCheck_xml.firstChild.firstChild.firstC
hild.nodeValue+
"\n";
//set
all
global
variables
from
SharedObject
_global
.
chatID
=
savedID
.
data
.
chatID
;
_global
.
userName
=
savedID
.
data
.
userName
;
_global
.
question
=
savedID
.
data
.
question
;
//then
skip
the
newChat
creation
straight
to
the
chat
//gotoAndPlay(26);
//chat
still
exists
=
true
_global
.
chatFound
=
true
;
1
StudentClientSource.as 6/6/2006
gotoAndPlay
(
"chatFrame"
)
;
}
else
{
//this
allows
the
keylistener
to
werk
if
the
chat
does
not
exist
anymore.
keyListener
=
new
Object
()
;
keyListener
.
onKeyDown
=
function
()
{
if
(
Key
.
isDown
(
Key
.
ENTER
))
{
_root
.
newChat
.
onRelease
()
;
}
}
;
Key
.
addListener
(
keyListener
)
;
}
//end
else
(if
false)
}
//end
if(success)
}
;
//end checkChat onLoad
/*************************************************************************/
//set new xml variable
newChatID_xml
=
new
XML
()
;
newChatID_xml
.
ignoreWhite
=
true
;
newChatID_xml
.
onLoad
=
function
(
success
)
{
if
(
success
)
{
processChatID
(
newChatID_xml
)
;
//gotoAndPlay(3);
}
//ELSE
throw
an
error????
}
;
//called when the button with instance id 'newChat' is released
_root
.
newChat
.
onRelease
=
function
()
{
if
(
userIDField_txt
.
length
!
=
0
&
&
questionField_txt
.
length
!
=
0
)
{
trace
(
"name:
"
+
userIDField_txt
.
text
)
;
trace
(
"question:
"
+
questionField_txt
.
text
)
;
_global
.
question
=
questionField_txt
.
text
;
_global
.
userName
=
userIDField_txt
.
text
;
newChatID_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?act
ion=newChat&name="
+
userIDField_txt
.
text
+
"&question="
+
questionField_txt
.
text
)
;
//_root.chatID
=
"0";
}
}
;
function
processChatID
(
xmlDoc_xml
)
{
//
xmlDoc_xml
is
now
a
reference
to
the
XML
//
object
where
our
information
is
stored
trace
(
"chatID=
"
+
xmlDoc_xml
.
firstChild
.
childNodes
[
0
])
;
_global
.
chatID
=
xmlDoc_xml
.
firstChild
.
childNodes
[
0
]
.
firstChild
.
nodeValue
;
if
(
_global
.
chatID
=
=
"closed"
)
{
gotoAndStop
(
2
)
;
}
else
{
//save
the
data
in
a
shared
object
to
save
the
session
//
shared
objects
in
actionscriopt/flash
are
like
cookies
savedID
.
data
.
chatID
=
_global
.
chatID
;
savedID
.
data
.
userName
=
_global
.
userName
;
savedID
.
data
.
question
=
_global
.
question
;
//_root.chatID
=
xmlDoc_xml.firstChild.childNodes[0];
gotoAndPlay
(
3
)
;
}
}
//Student Client closedFrame (Frame 2)
/*****************************************************************************
***********************/
/*****************************************************************************
***********************/
/*****************************************************************************
***********************/
2
StudentClientSource.as 6/6/2006
stop
()
;
//Student Client chatFrame (Frame 26)
/*****************************************************************************
***********************/
/*****************************************************************************
***********************/
/*****************************************************************************
***********************/
stop
()
;
sharedID
.
clear
()
;
keyListener
=
new
Object
()
;
keyListener
.
onKeyDown
=
function
(){
if
(
Key
.
isDown
(
Key
.
ENTER
)){
_root
.
submitButt
.
onRelease
()
;
}
}
Key
.
addListener
(
keyListener
)
;
/*****************************************************************************
***********/
//these two variables allow us to display the time the last message was sent
//after 30 sec of no new messages
var
isTimeDisplayed
:
Boolean
=
true
;
var
last_message_sent_at
:
String
=
""
;
var
last_timer_time
=
getTimer
()
;
this
.
tArea_txt
.
html
=
true
;
this
.
tArea_txt
.
condenseWhite
=
true
;
//this.tArea_txt.htmlText = this.tArea_txt.htmlText +"chatID= " +
_global.chatID+"\n";
//tArea_txt.text = tArea_txt.text +"length= " + _global.chatID.length;
this
.
tArea_txt
.
htmlText
=
this
.
tArea_txt
.
htmlText
+
"<br/><font
color='#FF0000'>Hi "
+
_global
.
userName
+
",<br /> Please wait for a WebCT
Administrator to become available.</font>"
;
this
.
tArea_txt
.
htmlText
=
this
.
tArea_txt
.
htmlText
+
"<br/><font
color='#FF0000'>Your initial question is: "
+
_global
.
question
+
"</font>"
;
//chatID = "0";
//this.tArea_txt.scroll = 0;
toDoList_xml
=
new
XML
()
;
toDoList_xml
.
ignoreWhite
=
true
;
messageList_xml
=
new
XML
()
;
messageList_xml
.
ignoreWhite
=
true
;
sendMessage_xml
=
new
XML
()
;
sendMessage_xml
.
ignoreWhite
=
true
;
messageList_xml
.
onLoad
=
function
(
success
)
{
if
(
success
)
{
processList
(
messageList_xml
)
;
}
}
getAllMessages
(
_global
.
chatFound
)
;
//toDoList_xml.load("http://localhost:8080/flashTest/servlet/FlashChat.XMLcom?
message=you%20smaell%20like%20poop");
//calls function getNewMessages with every 1000 miliseconds
var
getMessagesIntervalID
=
setInterval
(
getNewMessages
,
1500
)
;
/*****************************************************************************
***/
/* am attempt to scroll smoothly...
var i:Number = 0;
function onEnterFrame() {
if
(i
>
0)
3
StudentClientSource.as 6/6/2006
{
tArea_txt._height++;
tArea_txt._y--;
i--;
}
}*/
/*****************************************************************************
***/
function
getNewMessages
()
{
//Internet
Explorers
Flash
Player
caches
the
xmlfile,
so
we
need
messageList_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
getMessage&isTech=false&chatID="
+
_global
.
chatID
+
"&timer="
+
getTimer
())
;
}
// This is the function that will be called when
// our XML document is loaded succesfully
function
processList
(
xmlDoc_xml
)
{
// xmlDoc_xml is now a reference to the XML
// object where our information is stored
//check
if
ChatHel
is
Closed
if
(
xmlDoc_xml
.
firstChild
.
childNodes
[
0
]
.
firstChild
.
nodeValue
=
=
"closed"
)
{
clearInterval
(
getMessagesIntervalID
)
;
gotoAndStop
(
"ClosedDuringSession"
)
;
}
//end
if
chat
service
closed
else
if
(
xmlDoc_xml
.
firstChild
.
childNodes
[
0
]
.
firstChild
.
nodeValue
=
=
"chat
closed"
)
{
clearInterval
(
getMessagesIntervalID
)
;
gotoAndPlay
(
"Chat
Closed"
)
;
}
//
end
if
this
chat
has
been
ended/closed/killed
else
{
for
(
var
n
=
0
;
n
<
xmlDoc_xml
.
firstChild
.
childNodes
.
length
;
n
+
+
)
{
/*
System
Message
*/
if
(
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
attributes
.
name
=
=
"System"
)
{
this
.
tArea_txt
.
htmlText
=
this
.
tArea_txt
.
htmlText
+
"<font
color='#FF0000'>"
+
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
firstChild
.
nodeValue
+
"</font>"
;
isTimeDisplayed
=
false
;
last_message_sent_at
=
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
attributes
.
time
;
last_timer_time
=
getTimer
()
;
}
else
/*
Regular
Message
*/
{
var
color
:
String
=
"38ed00"
;
if
(
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
attributes
.
name
!
=
_global
.
userName
)
color
=
"0055f0"
;
this
.
tArea_txt
.
htmlText
=
this
.
tArea_txt
.
htmlText
+
"<b><font
color='#"
+
color
+
"'>"
+
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
attributes
.
name
+
"</font></b>:
"
+
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
firstChild
.
nodeValue
;
trace
(
n
+
' '
+
xmlDoc_xml
.
firstChild
.
childNodes
[
n
])
;
isTimeDisplayed
=
false
;
last_message_sent_at
=
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
attributes
.
time
;
4
StudentClientSource.as 6/6/2006
last_timer_time
=
getTimer
()
;
}
//this.tArea_txt._height
=
this.tArea_txt._height
+
12;
//this.tArea_txt._y
=
this.tArea_txt._y
-
12;
this
.
tArea_txt
.
scroll
=
this
.
tArea_txt
.
bottomScroll
;
}
// end for loop to process messages
}
//end
else
if
not
closed
}
//
end
processList(XML)
/*****************************************************************************
*******/
function
onEnterFrame
()
{
if
((
isTimeDisplayed
=
=
false
)
&
&
(
getTimer
()
-
45000
>
last_timer_time
))
{
tArea_txt
.
htmlText
=
tArea_txt
.
htmlText
+
"<b><font
color='#9b9b9b'>Sent
at
"
+
last_message_sent_at
+
"</font></b>"
;
tArea_txt
.
scroll
=
this
.
tArea_txt
.
bottomScroll
;
isTimeDisplayed
=
true
;
}
}
/*****************************************************************************
*******/
_root
.
submitButt
.
onRelease
=
function
(){
if
(
TextIn_txt
.
length
!
=
0
){
trace
(
"Buton
Clicked"
)
;
trace
(
"text:
"
+
TextIn_txt
.
text
)
;
trace
(
"chatID="
+
_root
.
chatID
)
;
sendMessage_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgener
ator?action=setMessage&isTech=false&chatID="
+
_global
.
chatID
+
"&message="
+
TextIn_txt
.
text
)
;
TextIn_txt
.
text
=
""
;
}
}
//end
submitButt.onRelease()
_root
.
exitButt
.
onRelease
=
function
()
{
savedID
.
clear
()
;
//
clear
shared
variable
var
leaveChatLink
:
String
=
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?act
ion=leaveChat&isTech=false&chatID="
+
_global
.
chatID
;
loadVariables
(
leaveChatLink
,
"_root"
)
;
getURL
(
"javascript:window.opener=self;
window.close()"
)
;
//
close
window
}
//end
exitButt.onRelease()
/*************************************************************************/
function
getAllMessages
(
isChatFound
:
Boolean
)
{
if
(
isChatFound
)
{
messageList_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
getAllMessages&isTech=false&chatID="
+
_global
.
chatID
+
"&timer="
+
getTimer
())
;
}
}
//end getAllMessages
5
AdministrativeAppSourse.as 6/6/2006
//Actionscript Frame 1
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
stop
()
;
isOpen_xml
=
new
XML
()
;
isOpen_xml
.
ignoreWhite
=
true
;
isOpen_xml
.
onLoad
=
function
(
success
)
{
if
(
success
){
_global
.
serverStatus
=
isOpen_xml
.
firstChild
.
childNodes
[
0
]
.
firstChild
.
nodeValue
;
if
(
_global
.
serverStatus
=
=
"closed"
)
gotoAndPlay
(
"Closed"
)
;
else
if
(
_global
.
serverStatus
=
=
"open"
)
gotoAndPlay
(
"Open"
)
;
}
}
isOpen_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=isOpen"
)
;
//Actionscript Frame 10
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
stop
()
;
enter_btn
.
onRelease
=
function
()
{
if
(
openAdminName_txt
.
text
!
=
""
)
{
_global
.
techID
=
openAdminName_txt
.
text
;
gotoAndPlay
(
11
)
;
}
}
//Actionscript Frame 20
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
gotoAndPlay
(
"moveTextBox"
)
;
//Actionscript Frame 30
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
stop
()
;
_global
.
techID
;
chatOpener
=
new
LoadVars
()
;
chatOpener
.
onLoad
=
function
(
success
){
_root
.
gotoAndPlay
(
31
)
;
}
openChat_btn
.
onRelease
=
function
()
{
if
(
openAdminName_txt
.
text
!
=
""
){
_global
.
techID
=
openAdminName_txt
.
text
;
chatOpener
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
openChat"
)
;
}
}
//Actionscript Frame 57
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
stop
()
;
1
AdministrativeAppSourse.as 6/6/2006
var
chatList_xml
:
XML
=
new
XML
()
;
chatList_xml
.
ignoreWhite
=
true
;
var
qCount
:
Number
;
var
sendCloseData
:
LoadVars
=
new
LoadVars
()
;
sendCloseData
.
onLoad
=
function
()
{
clearInterval
(
getChatsIntervalID
)
;
gotoAndStop
(
1
)
;
}
//qList = new Array();
chatList_xml
.
onLoad
=
function
(
success
)
{
if
(
success
)
{
refreshList
(
chatList_xml
)
;
}
}
/********************************************************************/
closeChat_btn
.
onRelease
=
function
(){
sendCloseData
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
closeChat"
)
;
}
/********************************************************************/
_root
.
onEnterFrame
=
function
()
{
//SCROLLING
if
(
qCount
>
4
|
|
((
_root
.
QuestionList_mc
.
_y
+
_root
.
QuestionList_mc
.
_height
)
>
_root
.
scrollDown_btn
.
_y
)
|
|
(
_root
.
QuestionList_mc
.
_y
<
(
_root
.
scrollUP_btn
.
_y
+
_root
.
scrollUP_btn
.
_height
))
)
{
//trace("QLy:
"+_root.QuestionList_mc._y+"\t
scrollUP
bottom:
"+(_root.scrollUP_btn._y
+
_root.scrollUP_btn._height)
);
//scroll
up
if
(
_root
.
_ymouse
>
_root
.
scrollUP_btn
.
_y
&
&
_root
.
_ymouse
<
(
_root
.
scrollUP_btn
.
_y
+
_root
.
scrollUP_btn
.
_height
)
&
&
_root
.
QuestionList_mc
.
_y
<
(
_root
.
scrollUP_btn
.
_y
+
_root
.
scrollUP_btn
.
_height
))
_root
.
QuestionList_mc
.
_y
=
_root
.
QuestionList_mc
.
_y
+
7
;
//scroll
Down
if
(
_root
.
_ymouse
>
_root
.
scrollDown_btn
.
_y
&
&
_root
.
_ymouse
<
(
_root
.
scrollDown_btn
.
_y
+
_root
.
scrollDown_btn
.
_height
)
&
&
(
_root
.
QuestionList_mc
.
_y
+
_root
.
QuestionList_mc
.
_height
)
>
_root
.
scrollDown_btn
.
_y
)
_root
.
QuestionList_mc
.
_y
=
_root
.
QuestionList_mc
.
_y
-
7
;
if
(
qCount
<
=
4
&
&
_root
.
QuestionList_mc
.
_y
<
(
_root
.
scrollUP_btn
.
_y
+
_root
.
scrollUP_btn
.
_height
))
_root
.
QuestionList_mc
.
_y
=
_root
.
QuestionList_mc
.
_y
+
10
;
if
(
qCount
>
4
&
&
(
_root
.
QuestionList_mc
.
_y
+
_root
.
QuestionList_mc
.
_height
)
<
(
_root
.
scrollDown_btn
.
_y
-
5
))
_root
.
QuestionList_mc
.
_y
=
_root
.
QuestionList_mc
.
_y
+
10
;
}
}
/********************************************************************/
AdminName_txt
.
onChanged
=
function
(){
_global
.
techID
=
AdminName_txt
.
text
;
}
/********************************************************************/
//chatList_xml.load("test.xml");
getAvailableChats
()
;
var
getChatsIntervalID
=
setInterval
(
getAvailableChats
,
5000
)
;
function
getAvailableChats
()
{
chatList_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
getAvailableChats"
)
;
2
AdministrativeAppSourse.as 6/6/2006
//chatList_xml.load("test.xml");
}
function
refreshList
(
xmlDoc_xml
)
{
removeQuestions
()
;
qCountTemp
=
0
;
//check
if
ChatHel
is
Closed
if
(
xmlDoc_xml
.
firstChild
.
childNodes
[
0
]
.
firstChild
.
nodeValue
=
=
"closed"
)
{
clearInterval
(
getChatsIntervalID
)
;
gotoAndStop
(
1
)
;
}
for
(
var
n
=
0
;
n
<
xmlDoc_xml
.
firstChild
.
childNodes
.
length
;
n
+
+
)
{
//this.tArea_txt.text
=
this.tArea_txt.text
+
'<b><font
color=\"grey\">'
+
xmlDoc_xml.firstChild.childNodes[n].attributes
.name
+
':</font></b>'
+
xmlDoc_xml.firstChild.childNodes[n];
// trace(n + ' ' + xmlDoc_xml.firstChild.childNodes[n]);
var
cID
:
Number
=
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
attributes
.
id
;
var
sName
:
String
=
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
childNodes
[
1
]
.
firstChild
.
nodeValue
;
var
sQuestion
:
String
=
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
childNodes
[
0
]
.
firstChild
.
nodeValue
;
var
movieName
:
String
=
'm'
+
n
;
var
startX
:
Number
=
74
;
var
startY
:
Number
=
n
*
78
+
39
;
//trace('Question
width:
'+Question._width)
//trace(xmlDoc_xml.firstChild.childNodes[n].at
tributes.id);
//trace(xmlDoc_xml.firstChild.childNodes[n].ch
ildNodes[0].firstChild.nodeValue);
//trace(xmlDoc_xml.firstChild.childNodes[n].ch
ildNodes[1].firstChild.nodeValue);
//trace('X:
'
+
startX
+
'
Y:
'
+startY);
_root
.
QuestionList_mc
.
attachMovie
(
"Question"
,
movieName
,
100
+
n
,
{
cID
:
cID
,
sName
:
sName
,
sQuestion
:
sQuestion
,
_x
:
startX
,
_y
:
startY
})
;
//qList.push(movieName);
qCountTemp
+
+
;
//trace("just
added...
qList:
"
+
qList.toString());
//_root.removeMovieClip("m0");
//trace("just
removed...
qList:
"
+
qList.toString());
//q.setPos(0,0);
}
qCount
=
qCountTemp
;
}
function
removeQuestions
()
{
/*while(qList.length
!=
0)
{
3
AdministrativeAppSourse.as 6/6/2006
trace("length
be4
pop:
"+qList.length);
_root.removeMovieClip(qList.pop);
qList.splice((qList.length
-
1),1);
trace("length
after
pop:
"+qList.length);
}
trace("everything
shoud
be
gone...
qList:
"
+qList.toString());
*/
var
i
=
qCount
;
while
(
-
-
i
>
-
1
)
{
//_root["m"+i].moveOver();
//trace("length
be4
pop:
"+qList.length);
_root
.
QuestionList_mc
[
"m"
+
i
]
.
removeQs
()
;
//qList.splice(i,1);
//trace("length
after
pop:
"+qList.length);
}
//trace("everything
shoud
be
gone...
qList:
"
+qList.toString());
}
//end
removeQuestions()
MovieClip
.
prototype
.
removeQs
=
function
()
{
this
.
removeMovieClip
()
;
}
4
AdminClientSource.as 6/6/2006
// Actionscript Frame 1
/********************************************************************/
/********************************************************************/
/********************************************************************/
//stops animation from continuing to next frame
stop
()
;
//sets variable chatID at root level
_root
.
chatID
;
//set new xml variable
newChatID_xml
=
new
XML
()
;
newChatID_xml
.
ignoreWhite
=
true
;
newChatID_xml
.
onLoad
=
function
(
success
)
{
if
(
success
)
{
processChatID
(
newChatID_xml
)
;
//gotoAndPlay(3);
}
else
{
gotoAndPlay
(
3
)
;
}
}
//called when the button with instance id 'newChat' is released
_root
.
newChat
.
onRelease
=
function
(){
trace
(
"name:
"
+
techIDField_txt
.
text
)
;
trace
(
"question:
"
+
chatIDField_txt
.
text
)
;
newChatID_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
pickChat&techID="
+
techIDField_txt
.
text
+
"&chatID="
+
chatIDField_txt
.
text
)
;
_root
.
chatID
=
chatIDField_txt
.
text
;
}
function
processChatID
(
xmlDoc_xml
)
{
gotoAndStop
(
2
)
;
}
//Actionscripo Frame 26
/********************************************************************/
/********************************************************************/
/********************************************************************/
stop
()
;
this
.
tArea_txt
.
condenseWhite
=
true
;
this
.
tArea_txt
.
text
=
""
;
tArea_txt
.
text
=
tArea_txt
.
text
+
"chatID= "
+
_root
.
chatID
+
"\n"
;
//tArea_txt.text = tArea_txt.text +"length= " + _root.chatID.length;
//chatID = "0";
toDoList_xml
=
new
XML
()
;
toDoList_xml
.
ignoreWhite
=
true
;
messageList_xml
=
new
XML
()
;
messageList_xml
.
ignoreWhite
=
true
;
1
AdminClientSource.as 6/6/2006
sendMessage_xml
=
new
XML
()
;
sendMessage_xml
.
ignoreWhite
=
true
;
messageList_xml
.
onLoad
=
function
(
success
)
{
if
(
success
)
{
processList
(
messageList_xml
)
;
}
}
//toDoList_xml.load("http://localhost:8080/flashTest/servlet/FlashChat.XMLcom?
message=you%20smaell%20like%20poop");
//calls function getNewMessages with every 1000 miliseconds
setInterval
(
getNewMessages
,
1500
)
;
function
getNewMessages
()
{
messageList_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
getMessage&isTech=true&chatID="
+
_root
.
chatID
)
;
}
// This is the function that will be called when
// our XML document is loaded succesfully
function
processList
(
xmlDoc_xml
)
{
// xmlDoc_xml is now a reference to the XML
// object where our information is stored
for
(
var
n
=
0
;
n
<
xmlDoc_xml
.
firstChild
.
childNodes
.
length
;
n
+
+
)
{
this
.
tArea_txt
.
text
=
this
.
tArea_txt
.
text
+
'<b><font color=\"grey\">'
+
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
.
attributes
.
name
+
':</font></b>'
+
xmlDoc_xml
.
firstChild
.
childNodes
[
n
]
;
trace
(
n
+
' '
+
xmlDoc_xml
.
firstChild
.
childNodes
[
n
])
;
}
}
_root
.
submitButt
.
onRelease
=
function
(){
trace
(
"Buton
Clicked"
)
;
trace
(
"text:
"
+
TextIn_txt
.
text
)
;
trace
(
"chatID="
+
_root
.
chatID
)
;
sendMessage_xml
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
setMessage&isTech=true&chatID="
+
_root
.
chatID
+
"&message="
+
TextIn_txt
.
text
)
;
TextIn_txt
.
text
=
""
;
}
2
Question.as 6/1/2006
dynamic
class
Question
extends
MovieClip
{
public
var
cID
:
Number
,
link
:
String
,
sName
:
String
,
sQuestion
:
String
,
selectIDButton
:
Button
,
closeChat_btn
:
Button
;
var
sender
:
LocalConnection
,
sendData
:
LoadVars
,
pickChat_xml
:
XML
;
function
Question
()
{
//trace("@cID= " + cID);
//trace("@name= " + sName);
sender
=
new
LocalConnection
()
;
sendData
=
new
LoadVars
()
;
sendData
.
onLoad
=
function
(
success
)
{
//_root.QuestionList_mc['m'+cID].removeMovieClip();
}
link
=
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
pickChat&chatID="
+
cID
+
"&techID="
+
_global
.
techID
;
pickChat_xml
=
new
XML
()
;
pickChat_xml
.
onLoad
=
function
(
success
)
{
if
(
success
)
{
}
else
{
fscommand
(
"exec"
,
"adminClient.exe"
)
;
//this._parent.sendChatIDtoClient();
}
}
this
.
closeChat_btn
.
onRelease
=
function
()
{
this
.
_parent
.
sendData
.
load
(
"http://localhost:8080/chat/servlet/FlashChat.XMLgenerator?action=
endChat&chatID="
+
this
.
_parent
.
cID
)
;
//fscommand("exec","deleteChatWarning.exe");
//this._parent.sendChatIDtoDeleteChat();
}
// end closeChat onRelease
}
//end constructor
function
onEnterFrame
()
{
//trace("#name= " + sName);
this
.
selectIDButton
.
onRelease
=
function
()
{
//trace("%cID= " + this._parent.cID);
//trace("%link= " + this._parent.link);
//trace("%name= " + this._parent.sName);
//_root.getURL("http://www.macromedia.com","_blank");
this
.
_parent
.
pickChat_xml
.
load
(
this
.
_parent
.
link
)
;
sendy
=
new
LocalConnection
()
;
for
(
var
i
=
100
;
i
>
0
;
i
-
-
)
sendy
.
send
(
"ChatID_to_AdminClientApp"
,
"executeOnRecieve"
,
this
.
_parent
.
cID
,
this
.
_parent
.
sName
,
this
.
_parent
.
sQuestion
,
_global
.
techID
)
;
//
trace("thisparent:
"+this._parent.cID);
//trace("root:
"+_root.cID);
//trace("thisparentparent:
"+this._parent._parent.cID);
1
Question.as 6/1/2006
//trace("this:
"+this.cID);
//trace("thisparentparentparent:
"+this._parent._parent._parent.cID);
//trace("techID:
"+_global.techID);
sendy
.
close
()
;
//fscommand("exec","adminClient.exe");
//for(var i =100;i>0;i--)
//this._parent.sender.send("ChatID_to_AdminClientApp","executeOnRecieve",this.
_parent.cID,this._parent.sName,this._parent.sQuestion,_global.techID);
//this._parent.sender.close();
//delete sender2;
//this._parent.removeMovieClip();
//this._parent.sendChatIDtoClient();
//sender.close();
/////////////////////////////////////////////
/////////////////////////////////////////////
}
//end pickChat onRelease
}
//end onEnterFrame
function
sendChatIDtoDeleteChat
()
{
sender2
=
new
LocalConnection
()
;
//trace("cID: "+cID);
//burns time to make sure the client app recieves the cID
for
(
var
i
=
100
;
i
>
0
;
i
-
-
)
sender2
.
send
(
"ChatID_to_DeleteChatApp"
,
"executeOnRecieve"
,
cID
,
sName
,
sQuestion
)
;
delete
sender2
;
}
//end sendChatIDtoDeleteChat()
function
sendChatIDtoClient
()
{
fscommand
(
"exec"
,
"adminClient.exe"
)
;
for
(
var
i
=
1000
;
i
>
0
;
i
-
-
)
this
.
_parent
.
sender
.
send
(
"ChatID_to_AdminClientApp"
,
"executeOnRecieve"
,
this
.
_parent
.
cID
,
this
.
_parent
.
sName
,
this
.
_parent
.
sQuestion
,
_global
.
techID
)
;
this
.
_parent
.
sender
.
close
()
;
}
//end sendChatIDtoClient()
function
moveOver
()
{
2
Question.as 6/1/2006
sName
=
"newName"
;
}
//end move over
}
//end class
3
XMLgenerator.java 6/2/2006
/*
* XMLgenerator.java
*
* Created on March 12, 2006, 11:47 AM
*/
package
FlashChat
;
import
java
.
io
.
*
;
import
java
.
net
.
*
;
import
java
.
util
.
*
;
import
javax
.
servlet
.
*
;
import
javax
.
servlet
.
http
.
*
;
/**
*
* @author nico
* @version
*/
public
class
XMLgenerator
extends
HttpServlet
{
/** Processes requests for both HTTP <code>GET</code> and
<code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
ChatManager
chatMan
;
String
action
;
int
chatID
;
boolean
isTech
;
private
int
counter
=
0
;
public
void
init
(){
chatMan
=
new
ChatManager
()
;
}
protected
void
processRequest
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException
,
IOException
{
response
.
setContentType
(
"text/xml;charset=UTF-8"
)
;
PrintWriter
out
=
response
.
getWriter
()
;
/* TODO output your page here
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet XMLcom</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Servlet XMLcom at " + request.getContextPath () +
"</h1>");
out.println("</body>");
out.println("</html>");
*/
if
(
request
.
getParameter
(
"action"
)
!
=
null
)
action
=
request
.
getParameter
(
"action"
)
;
if
(
chatMan
.
isChatOpen
())
{
if
(
request
.
getParameter
(
"chatID"
)
!
=
null
)
chatID
=
Integer
.
parseInt
(
request
.
getParameter
(
"chatID"
))
;
if
(
request
.
getParameter
(
"isTech"
)
!
=
null
)
isTech
=
Boolean
.
parseBoolean
(
request
.
getParameter
(
"isTech"
))
;
//New Chat
1
XMLgenerator.java 6/2/2006
if
(
action
.
equals
(
"newChat"
))
{
int
id
=
chatMan
.
setNewChat
(
request
.
getParameter
(
"name"
)
.
trim
()
,
request
.
getParameter
(
"question"
)
.
trim
())
;
out
.
println
(
"<messageSet>"
)
;
out
.
println
(
"<chatID>"
+
id
+
"</chatID>"
)
;
out
.
println
(
"</messageSet>"
)
;
out
.
close
()
;
}
// chatMan.getAvailableChat()
if
(
action
.
equals
(
"getAvailableChats"
))
{
out
.
println
(
"<availableChats>"
)
;
for
(
Chat
c
:
chatMan
.
getAvailableChat
())
{
out
.
println
(
"<chat id=\""
+
c
.
getChatID
()
+
"\" >"
)
;
out
.
println
(
"<question>"
+
c
.
getQuestion
()
+
"</question>"
)
;
out
.
println
(
"<guestID>"
+
c
.
getGuestID
()
+
"</guestID>"
)
;
out
.
println
(
"</chat>"
)
;
}
out
.
println
(
"</availableChats>"
)
;
}
// chatMan.setCurrentChat(techID, chatID)
if
(
action
.
equals
(
"pickChat"
))
{
boolean
pickable
=
false
;
for
(
Chat
c
:
chatMan
.
getAvailableChat
())
if
(
c
.
getTechID
()
=
=
null
)
pickable
=
true
;
if
(
pickable
)
chatMan
.
setCurrentChat
(
request
.
getParameter
(
"techID"
)
.
trim
()
,
chatID
)
;
else
{
out
.
println
(
"<SystemMessage>"
)
;
out
.
println
(
"<message>chat taken</message>"
)
;
out
.
println
(
"</SystemMessage>"
)
;
}
}
// Set Message
if
(
action
.
equals
(
"setMessage"
))
{
chatMan
.
setNewMessage
(
chatID
,
request
.
getParameter
(
"message"
)
,
isTech
)
;
}
// Get Message
if
(
action
.
equals
(
"getMessage"
))
{
if
(
chatMan
.
doesChatExist
(
chatID
)){
out
.
println
(
"<messageSet>"
)
;
for
(
Message
m
:
chatMan
.
getNewMessages
(
chatID
,
isTech
))
{
out
.
print
(
"<message name=\""
+
m
.
getFrom
()
+
"\" time=\""
+
m
.
getStringDate
()
+
"\">"
)
;
out
.
print
(
m
.
getMessage
())
;
out
.
print
(
"</message>"
)
;
2
XMLgenerator.java 6/2/2006
}
out
.
println
(
"</messageSet>"
)
;
}
else
{
out
.
println
(
"<SystemMessage>"
)
;
out
.
println
(
"<message>chat closed</message>"
)
;
out
.
println
(
"</SystemMessage>"
)
;
}
}
//Get all messages
if
(
action
.
equals
(
"getAllMessages"
))
{
out
.
println
(
"<messageSet>"
)
;
for
(
Message
m
:
chatMan
.
getAllMessages
(
chatID
,
isTech
))
{
out
.
print
(
"<message name=\""
+
m
.
getFrom
()
+
"\" time=\""
+
m
.
getStringDate
()
+
"\">"
)
;
out
.
print
(
m
.
getMessage
())
;
out
.
print
(
"</message>"
)
;
}
out
.
println
(
"</messageSet>"
)
;
out
.
close
()
;
}
if
(
action
.
equals
(
"endChat"
))
{
chatMan
.
deleteAChat
(
chatID
)
;
}
if
(
action
.
equals
(
"checkChat"
))
{
out
.
println
(
"<SystemMessage>"
)
;
out
.
println
(
"<message>"
+
Boolean
.
toString
(
chatMan
.
doesChatExist
(
chatID
))
+
"</message>"
)
;
out
.
println
(
"</SystemMessage>"
)
;
}
if
(
action
.
equals
(
"closeChat"
))
{
chatMan
.
setChatOpen
(
false
)
;
}
if
(
action
.
equals
(
"leaveChat"
))
{
chatMan
.
leaveChat
(
chatID
,
isTech
)
;
}
if
(
action
.
equals
(
"isOpen"
))
{
out
.
println
(
"<SystemMessage>"
)
;
out
.
println
(
"<message>open</message>"
)
;
out
.
println
(
"</SystemMessage>"
)
;
}
}
//end check if ChatOpen
else
if
(
action
.
equals
(
"openChat"
))
{
chatMan
.
setChatOpen
(
true
)
;
}
else
{
out
.
println
(
"<SystemMessage>"
)
;
3
XMLgenerator.java 6/2/2006
out
.
println
(
"<message>closed</message>"
)
;
out
.
println
(
"</SystemMessage>"
)
;
}
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click
on the + sign on the left to edit the code.">
/** Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected
void
doGet
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException
,
IOException
{
processRequest
(
request
,
response
)
;
}
/** Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected
void
doPost
(
HttpServletRequest
request
,
HttpServletResponse
response
)
throws
ServletException
,
IOException
{
processRequest
(
request
,
response
)
;
}
/** Returns a short description of the servlet.
*/
public
String
getServletInfo
()
{
return
"Short description"
;
}
// </editor-fold>
}
4
ChatManager.java 6/1/2006
package
FlashChat
;
import
java
.
util
.
*
;
public
class
ChatManager
{
private
List
<
Chat
>
currentChats
;
private
List
<
Chat
>
availableChats
;
private
Random
idGenerator
;
private
List
<
Chat
>
chats
;
private
int
totalChats
;
private
boolean
chatOpen
;
/** Creates a new instance of ChatManager */
public
ChatManager
()
{
//currentChats = new ArrayList<Chat>();
//availableChats= new ArrayList<Chat>();
chats
=
new
ArrayList
<
Chat
>
()
;
chatOpen
=
false
;
totalChats
=
0
;
idGenerator
=
new
Random
()
;
}
public
boolean
isChatOpen
()
{
return
chatOpen
;
}
public
void
setChatOpen
(
boolean
isOpen
)
{
chatOpen
=
isOpen
;
if
(
isOpen
=
=
false
)
chats
.
clear
()
;
}
// this is called when a guest first requests to chat the user defines the
guestID and the question
public
int
setNewChat
(
String
guestID
,
String
question
)
{
int
id
=
createNewChatID
()
;
//availableChats.add(new Chat(id, guestID, question));
chats
.
add
(
new
Chat
(
id
,
guestID
,
question
))
;
return
id
;
}
public
boolean
deleteAChat
(
int
chatID
)
{
boolean
deleted
=
false
;
for
(
Chat
d
:
chats
)
{
if
(
d
.
getChatID
()
=
=
chatID
)
{
chats
.
remove
(
d
)
;
deleted
=
true
;
}
}
return
deleted
;
}
//this gives the chat a unique ID, could be expanded later.
private
int
createNewChatID
()
{
return
Math
.
abs
(
idGenerator
.
nextInt
())
;
}
//this creates a list of all chats that are in the availableChats List
// and returns them as comma delimited strings
1
ChatManager.java 6/1/2006
public
List
<
Chat
>
getAvailableChat
(){
List
<
Chat
>
aChatList
=
new
ArrayList
<
Chat
>
()
;
for
(
Chat
a
:
chats
)
{
if
(
a
.
getTechID
()
=
=
null
)
aChatList
.
add
(
a
)
;
}
return
aChatList
;
//return availableChats;
}
public
boolean
doesChatExist
(
int
chatID
)
{
boolean
exists
=
false
;
for
(
Chat
c
:
chats
)
if
(
c
.
getChatID
()
=
=
chatID
)
exists
=
true
;
return
exists
;
}
//this is called when a tech selects a chat out of the available chats
//it calls getAChat which returns a specific chat and removes it from the
// availableChats list. setCurrentChat then adds it to the currentChats
list
// and finaly it adds the techID to the chat.
/*
public void setCurrentChat(String techID, int chatID){
currentChats.add(getAChat(chatID));
deleteAChat(chatID);
for ( Chat c : currentChats)
if (c.getChatID() == chatID)
c.setTechID(techID);
}*/
public
void
setCurrentChat
(
String
techID
,
int
chatID
)
{
for
(
Chat
c
:
chats
)
if
(
c
.
getChatID
()
=
=
chatID
)
{
if
(
c
.
getTechID
()
=
=
null
){
c
.
setTechID
(
techID
)
;
c
.
setSystemMessage
(
"The administrator "
+
techID
+
", has
entered the chat session."
,
"user"
)
;
}
}
}
/*
*this is called when a tech leaves the current chat without ending it
*it sets the TechID on a specific chat to null
*/
public
void
leaveChat
(
int
chatID
,
boolean
isTech
)
{
for
(
Chat
c
:
chats
)
if
(
c
.
getChatID
()
=
=
chatID
)
{
if
(
isTech
){
c
.
setSystemMessage
(
"The administrator "
+
c
.
getTechID
()
+
",
has left the chat session."
,
"user"
)
;
c
.
setTechID
(
null
)
;
}
else
{
c
.
setSystemMessage
(
"The user "
+
c
.
getGuestID
()
+
", has left
the chat session."
,
"admin"
)
;
c
.
setIsUserGone
(
true
)
;
}
}
2
ChatManager.java 6/1/2006
}
//this is called by the setCurrentChat method and it returns a Chat that
has
// been removed from the availableChats list.
/* private Chat getAChat(int chatID)
{
Chat tempChat = new Chat();
for(Chat d : availableChats)
if (d.getChatID() == chatID){
try{tempChat = d.clone();}
catch(Exception e){}
}

return tempChat;
}


private boolean deleteAChat(int chatID)
{
boolean deleted= false;
for(Chat d : availableChats)
{ if(d.getChatID() == chatID)
{ availableChats.remove(d);
deleted=true;

}
}
return deleted;
}
*/
//this method isnt going to work.
/* public void getLatest(int chatID, boolean isTech)
{
Date t = new Date();
for (Chat c : currentChats)
if (c.getChatID()==chatID)
c.getMessagesAfter(t,isTech);
}
*/
/* public HashMap<Date,String> getNewMessages(int chatID, boolean isTech)
{
HashMap<Date, String> newMessages = new HashMap<Date, String>();
for (Chat c : currentChats)
if (c.getChatID()==chatID)
c.getNextMessages(t,isTech);


}
*/
// this method returns the newMessages for either the tech or the
user/guest
public
List
<
Message
>
getNewMessages
(
int
chatID
,
boolean
isTech
)
{
List
<
Message
>
newMessages
=
new
ArrayList
<
Message
>
()
;
for
(
Chat
c
:
chats
)
if
(
c
.
getChatID
()
=
=
chatID
)
newMessages
=
c
.
getNextMessages
(
isTech
)
;
return
newMessages
;
}
/*
*this method will return all the messages of a particular chat
*/
public
List
<
Message
>
getAllMessages
(
int
chatID
,
boolean
isTech
)
{
3
ChatManager.java 6/1/2006
List
<
Message
>
allMessages
=
new
ArrayList
<
Message
>
()
;
for
(
Chat
c
:
chats
)
if
(
c
.
getChatID
()
=
=
chatID
)
allMessages
=
c
.
getAllMessages
(
isTech
)
;
return
allMessages
;
}
// this method sets a new message for either the tech or the user/guest
public
void
setNewMessage
(
int
chatID
,
String
message
,
boolean
isTech
)
{
for
(
Chat
c
:
chats
)
if
(
c
.
getChatID
()
=
=
chatID
)
c
.
setMessage
(
message
,
isTech
)
;
}
}
4
Chat.java 6/3/2006
/*
* Chat.java
* Created on March 4, 2006, 3:30 PM
* This class povides all the details of a specific chat session including
* chatid, guest and tech id's, and holds the chat messages amogst other
things
*/
package
FlashChat
;
import
java
.
util
.
*
;
public
class
Chat
implements
Cloneable
{
private
int
chatID
;
private
String
guestID
;
private
String
techID
;
//private HashMap<Date,String> messages;
private
List
<
Message
>
messages
;
private
String
question
;
private
int
newMessagesTech
=
0
;
private
int
newMessagesGuest
=
0
;
private
boolean
isGuestTyping
=
false
;
private
boolean
isTechTyping
=
false
;
private
long
lastTechAccess
=
0
;
private
long
lastGuestAccess
=
0
;
private
long
keepAliveTime
=
5000
;
private
boolean
isUserGone
=
true
;
//default chat
public
Chat
()
{
}
/**
*
* Creates a new instance of Chat
* @param chatID id of chat to be created
* @param guestID id of guest in this chat
* @param question the question asssociated with this chat
*/
public
Chat
(
int
chatID
,
String
guestID
,
String
question
)
{
this
.
setChatID
(
chatID
)
;
this
.
setGuestID
(
guestID
)
;
this
.
setQuestion
(
question
)
;
//messages = new HashMap<Date,String>(); //I was goin to use a
HashMap to hold Messages
messages
=
new
ArrayList
<
Message
>
()
;
// but then I opted
for a list because its ordered
this
.
lastGuestAccess
=
new
Date
()
.
getTime
()
;
isUserGone
=
false
;
}
public
void
setIsUserGone
(
boolean
gone
)
{
this
.
isUserGone
=
gone
;
}
/* public void setMessage(Date time, String message){
messages.put(time, message);
newMessagesTech++;
newMessagesGuest++;
}
*/
/**
1
Chat.java 6/3/2006
*
* called whenever someone sends a message
* @param message message to be added to chat
* @param isTech is the person setting the message a Tech
*/
public
void
setMessage
(
String
message
,
Boolean
isTech
){
String
user
;
//set the user string to put in
Message
if
(
isTech
)
user
=
techID
;
//if the message is from tech user =
techID
else
user
=
guestID
;
//otherwise user = guestID
messages
.
add
(
new
Message
(
user
,
message
))
;
newMessagesTech
+
+
;
// increment the message count
newMessagesGuest
+
+
;
// increment the message count
}
/**
*sets system messages
*system messages are called whenever a Tech leaves the conversation
*whenever a tech enters the conversation
*/
public
void
setSystemMessage
(
String
message
,
String
to
)
{
messages
.
add
(
new
Message
(
"System"
,
message
))
;
if
(
to
.
equals
(
"user"
))
{
newMessagesGuest
+
+
;
}
else
if
(
to
.
equals
(
"admin"
))
{
newMessagesTech
+
+
;
}
else
{
newMessagesTech
+
+
;
newMessagesGuest
+
+
;
}
}
/*
public HashMap<Date,String> getMessagesAfter(Date time, boolean isTech){
HashMap<Date,String> temp = new HashMap<Date,String>();

for (Map.Entry<Date,String> entry : messages.entrySet() )
{
if (entry.getKey().after(time))
{ temp.put(entry.getKey(), entry.getValue());
//adjust the new messages count for the person requesting the
message
if (isTech)
newMessagesTech--;
else
newMessagesGuest--;
}

}
//for (Date t : messages.keySet()){}
return temp;
}
*/
/*
*
* this method is called whenever the server is queried for an update for
the chat (every 1 or 2 sec)
* @returns a list of messages that have not been seen by the particular
user (Tech or guest)
* @param isTech boolean that is true if the user is a Tech/admin
*/
public
List
<
Message
>
getNextMessages
(
boolean
isTech
)
{
List
<
Message
>
newMessages
=
new
ArrayList
<
Message
>
()
;
// add the last (Int)newMessages in messages to (List)newMessages
2
Chat.java 6/3/2006
// and while your at it decrement newMessages for whichever user is
accessing
if
(
isTech
)
{
long
timeNow
=
new
Date
()
.
getTime
()
;
if
(
lastGuestAccess
<
timeNow
-
keepAliveTime
&
&
!
isUserGone
)
{
setSystemMessage
(
"The user "
+
guestID
+
" has left the chat
session."
,
"admin"
)
;
isUserGone
=
true
;
// dont wanna keep hearing messages over
and over again!
}
while
(
newMessagesTech
>
0
)
newMessages
.
add
(
messages
.
get
(
messages
.
size
()
-
(
newMessagesTech
-
-
)))
;
lastTechAccess
=
timeNow
;
}
else
{
long
timeNow
=
new
Date
()
.
getTime
()
;
if
(
lastTechAccess
<
timeNow
-
keepAliveTime
&
&
techID
!
=
null
&
&
lastTechAccess
!
=
0
)
{
setSystemMessage
(
"The administrator "
+
techID
+
" has left the chat
session."
,
"user"
)
;
techID
=
null
;
//set the tech ID to null so it will apear in
the available chats list
lastTechAccess
=
0
;
// reset the counter so that when we pick
a chat we dont booted out again
}
while
(
newMessagesGuest
>
0
)
newMessages
.
add
(
messages
.
get
(
messages
.
size
()
-
(
newMessagesGuest
-
-
)))
;
lastGuestAccess
=
timeNow
;
}
return
newMessages
;
}
/*
*this method returns all the messages in the conversation
*/
public
List
<
Message
>
getAllMessages
(
boolean
isTech
)
{
if
(
isTech
)
newMessagesTech
=
0
;
else
{
newMessagesGuest
=
0
;
if
(
isUserGone
)
setSystemMessage
(
"The user "
+
guestID
+
" has
returned."
,
"admin"
)
;
isUserGone
=
false
;
}
return
messages
;
}
/**
*
* @return chatID the chats ID number
*/
public
int
getChatID
()
{
return
chatID
;
}
public
void
setChatID
(
int
chatID
)
{
3
Chat.java 6/3/2006
this
.
chatID
=
chatID
;
}
public
String
getGuestID
()
{
return
guestID
;
}
public
void
setGuestID
(
String
guestID
)
{
this
.
guestID
=
guestID
;
}
public
String
getTechID
()
{
return
techID
;
}
public
void
setTechID
(
String
techID
)
{
this
.
techID
=
techID
;
lastTechAccess
=
new
Date
()
.
getTime
()
;
}
public
String
getQuestion
()
{
return
question
;
}
public
void
setQuestion
(
String
question
)
{
this
.
question
=
question
;
}
public
Chat
clone
()
throws
CloneNotSupportedException
{
return
(
Chat
)
super
.
clone
()
;
}
}
4
Message.java 6/3/2006
package
FlashChat
;
import
java
.
util
.
*
;
public
class
Message
{
private
Calendar
cal
;
private
String
from
;
private
String
message
;
/** Creates a new instance of Message */
public
Message
(
String
from
,
String
message
)
{
this
.
cal
=
Calendar
.
getInstance
()
;
this
.
from
=
from
;
this
.
message
=
message
;
}
public
Calendar
getDate
()
{
return
cal
;
}
public
String
getStringDate
()
{
int
hour
=
cal
.
get
(
Calendar
.
HOUR
)
;
if
(
hour
=
=
0
)
hour
=
12
;
String
minute
=
String
.
valueOf
(
cal
.
get
(
Calendar
.
MINUTE
))
;
if
(
minute
.
length
()
=
=
1
)
minute
=
"0"
+
minute
;
String
amPm
=
"AM"
;
if
(
cal
.
get
(
Calendar
.
AM_PM
)
=
=
1
)
amPm
=
"PM"
;
int
weekDay
=
cal
.
get
(
Calendar
.
DAY_OF_WEEK
)
;
String
sWeekDay
=
""
;
int
month
=
cal
.
get
(
Calendar
.
MONTH
)
;
String
sMonth
=
""
;
int
date
=
cal
.
get
(
Calendar
.
DAY_OF_MONTH
)
;
// Get day of week
switch
(
weekDay
)
{
case
0
:
sWeekDay
=
"Sunday"
;
break
;
case
1
:
sWeekDay
=
"Monday"
;
break
;
case
2
:
sWeekDay
=
"Tuesday"
;
break
;
case
3
:
sWeekDay
=
"Wednesday"
;
break
;
case
4
:
sWeekDay
=
"Thursday"
;
break
;
case
5
:
sWeekDay
=
"Friday"
;
break
;
case
6
:
sWeekDay
=
"Saturday"
;
break
;
default
:
sWeekDay
=
"Saturday"
;
break
;
}
// Get Month
switch
(
month
)
{
case
0
:
sMonth
=
"Jan."
;
break
;
case
1
:
sMonth
=
"Feb."
;
break
;
case
2
:
sMonth
=
"Mar."
;
break
;
case
3
:
sMonth
=
"Apr."
;
break
;
case
4
:
sMonth
=
"May"
;
break
;
case
5
:
sMonth
=
"June"
;
break
;
case
6
:
sMonth
=
"July"
;
break
;
case
7
:
sMonth
=
"Aug."
;
break
;
case
8
:
sMonth
=
"Sep."
;
break
;
case
9
:
sMonth
=
"Oct."
;
break
;
case
10
:
sMonth
=
"Nov."
;
break
;
case
11
:
sMonth
=
"Dec."
;
break
;
}
return
hour
+
":"
+
minute
+
" "
+
amPm
+
" "
+
sWeekDay
+
" "
+
sMonth
+
" "
+
(
date
+
1
)
;
}
public
String
getFrom
()
{
return
from
;
}
public
String
getMessage
()
{
1
Message.java 6/3/2006
return
message
;
}
}
2