You can subscribe to this list here.
2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(16) |
Sep
(10) |
Oct
(1) |
Nov
(2) |
Dec
|
---|---|---|---|---|---|---|---|---|---|---|---|---|
2003 |
Jan
(148) |
Feb
(80) |
Mar
(41) |
Apr
(85) |
May
(247) |
Jun
(345) |
Jul
(237) |
Aug
(241) |
Sep
(439) |
Oct
(321) |
Nov
(413) |
Dec
(302) |
2004 |
Jan
(143) |
Feb
(147) |
Mar
(200) |
Apr
(107) |
May
(15) |
Jun
(36) |
Jul
(11) |
Aug
(1) |
Sep
(36) |
Oct
|
Nov
(6) |
Dec
|
2005 |
Jan
|
Feb
|
Mar
|
Apr
(115) |
May
(74) |
Jun
(215) |
Jul
(82) |
Aug
(47) |
Sep
(32) |
Oct
(8) |
Nov
(70) |
Dec
(24) |
2006 |
Jan
|
Feb
(1) |
Mar
(4) |
Apr
(2) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
2007 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2016 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <fza...@us...> - 2005-11-30 22:02:10
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/daemon In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12995/daemon Log Message: Directory /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/daemon added to the repository |
From: <fza...@us...> - 2005-11-29 23:46:23
|
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs/ajaxchat In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv969/src/documentation/content/xdocs/ajaxchat Added Files: index.xml Log Message: --- NEW FILE: index.xml --- <?xml version="1.0"?> <!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V1.1//EN" "document-v11.dtd"> <document> <header> <title>AjaxChat</title> </header> <body> <section id="overview"> <title>Overview</title> <p> We've all heard the buzz about this AJAX thing, and over and over there are questions asked on the Struts mailing lists about how to use AJAX in a Struts app. Well, now you have what is, hopefully, a good real-world example of doing just that! This is your typical chat application ala Yahoo! Chat, built on Struts and utilizing AJAX techniques. It is hoped that this shows how to meld the two together to produce applications that might not otherwise be possible. </p> </section> <section id="features"> <title>Features</title> <ul> <li>Multiple simultaneous users can chat in multiple rooms</li> <li>Rooms can be configured via XML config file</li> <li>Cross-browser (tested in IE 6.0 and FireFox 1.0)</li> <li>The ability to change font sizes and colors (your and theirs)</li> <li>Real, live demo available <link href="http://www.omnytex.com/ajaxchat">here</link></li> </ul> </section> <section id="new"> <title>What's New</title> <section> <title>AjaxChat initial release!</title> <p> 11/29/2005 - Version 1.0 alpha is now available for download! </p> </section> </section> <section id="usage"> <title>Usage</title> <p> At present, AjaxChat is available in a zip archive that is an exploded webapp. Simply unzip it into the appropriate location in your servlet container of choice and you should be all set. It *may* be necessary to also add the Commons Validator to WEB-INF/lib in some containers. This will be rectified in a future release. </p> </section> <section id="contact"> <title>Contact</title> <p> Please contact <link href="mailto:fza...@om...">Frank W. Zammetti</link> with questions, comments and suggestions. </p> </section> <section id="contributors"> <title>Contributors</title> <p> Frank W. Zammetti is the only current contributor. Well, that's not *entirely* true... Wendy Smoak has helped test this on occassion, so I suppose you could call her a contributor! <br/> </p> </section> </body> </document> |
From: <fza...@us...> - 2005-11-29 23:46:23
|
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv969/src/documentation/content/xdocs Modified Files: index.xml Log Message: Index: index.xml =================================================================== RCS file: /cvsroot/struts/struts-site/src/documentation/content/xdocs/index.xml,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** index.xml 11 Sep 2005 01:46:38 -0000 1.14 --- index.xml 29 Nov 2005 23:46:15 -0000 1.15 *************** *** 59,62 **** --- 59,66 ---- see the important note about this project on the AjaxTags page) </li> + <li> + <em>AjaxChat</em> - A Struts-based chat application utilizing AJAX techniques. This is meant to serve as an example for those wondering + how to use AJAX within a Struts app. + </li> </ul> <p> *************** *** 89,93 **** <strong>Struts Dialogs</strong><br /> This Struts library allows building stateful <em>web components</em> using Struts and JSP. ! Do you like JSF component model or portlet visual integration, but want to leverage your knowledge of Struts and JSP? Do you want to get rid of double submit problem? Do you want to create robust multi-page wizards? Do you want to simplify your source code? Try Struts Dialogs! --- 93,97 ---- <strong>Struts Dialogs</strong><br /> This Struts library allows building stateful <em>web components</em> using Struts and JSP. ! Do you like JSF component model or portlet visual integration, but want to leverage your knowledge of Struts and JSP? Do you want to get rid of double submit problem? Do you want to create robust multi-page wizards? Do you want to simplify your source code? Try Struts Dialogs! *************** *** 123,126 **** --- 127,138 ---- might be just the ticket! (please see the important note about this project on the AjaxTags page) </p> + <p> + <strong>AjaxChat</strong><br /> + We've all heard the buzz about this AJAX thing, and over and over there are questions asked on the + Struts mailing lists about how to use AJAX in a Struts app. Well, now you have what is, hopefully, a + good real-world example of doing just that! This is your typical chat application ala Yahoo! Chat, + built on Struts and utilizing AJAX techniques. It is hoped that this shows how to meld the two + together to produce applications that might not otherwise be possible. + </p> </section> |
From: <fza...@us...> - 2005-11-29 23:45:49
|
Update of /cvsroot/struts/struts-site/src/documentation/content/xdocs/ajaxchat In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv882/ajaxchat Log Message: Directory /cvsroot/struts/struts-site/src/documentation/content/xdocs/ajaxchat added to the repository |
Update of /cvsroot/struts/ajaxchat/WEB-INF/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src Added Files: ant-dependencies.jar build.xml checkstyle.xml commons-logging.properties javadoc_overview.htm simplelog.properties Log Message: --- NEW FILE: ant-dependencies.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: build.xml --- <project name="AjaxChat" basedir="." default="build"> <!-- ****************************************************************** --> <!-- ** Build properties. ** --> <!-- ****************************************************************** --> <!-- "javadocs" is the directory where generated javadocs will be --> <!-- placed if the javadoc task is executed. --> <property name="javadocs" value="javadocs" /> <!-- "project_version" is, obviously, the version of the app! --> <property name="project_version" value="1.0" /> <!-- "proxy_host" is the address of the proxy server that will be --> <!-- used to download dependencies, if a proxy is required on your --> <!-- network. If no proxy is required, leave this blank (bute note --> <!-- that the property MUST be defined either way! --> <property name="proxy_host" value="" /> <!-- "proxy_post" is the port of the proxy server that will be --> <!-- used to download dependencies, if a proxy is required on your --> <!-- network. If no proxy is required, leave this set to "80". --> <property name="proxy_port" value="80" /> <!-- "distro_dir" is the directory where the generated distribution --> <!-- file will be placed as a result of executing the optional distro --> <!-- target. --> <property name="distro_dir" value="c:\temp" /> <!-- ****************************************************************** --> <!-- ** Define runtime classpath. These JARs are needed to run the ** --> <!-- ** application, as well as building it. ** --> <!-- ****************************************************************** --> <path id="runtime_classpath"> <pathelement path="../lib/commons-beanutils-1.7.0.jar" /> <pathelement path="../lib/commons-digester-1.7.jar" /> <pathelement path="../lib/commons-lang-2.1.jar" /> <pathelement path="../lib/commons-logging-1.0.4.jar" /> <pathelement path="../lib/struts-1.2.7.jar" /> </path> <!-- ****************************************************************** --> <!-- ** Default target that should usually be executed. ** --> <!-- ****************************************************************** --> <target name="build"> <get_dependencies /> <antcall target="compile" inheritRefs="true" /> <!--<antcall target="checkstyle" inheritRefs="true" />--> <!--<antcall target="javadocs" inheritRefs="true" />--> </target> <!-- ****************************************************************** --> <!-- ** Define the macro to download dependencies from Maven ** --> <!-- ** repository. This also populates the compiletime_classpath, ** --> <!-- ** which is the collection of JARs needed to build the app, ** --> <!-- ** but not to run it. ** --> <!-- ****************************************************************** --> <macrodef name="get_dependencies"> <sequential> <echo message="Retrieving compile-time dependencies..." /> <setproxy proxyhost="${proxy_host}" proxyport="${proxy_port}" /> <typedef classpath="ant-dependencies.jar" resource="dependencies.properties" /> <dependencies pathId="compiletime_classpath" verbose="true"> <!-- Servlet/JSP dependencies --> <dependency group="servletapi" version="2.3" /> <!-- Checkstyle dependencies --> <dependency group="checkstyle" version="3.4" /> <dependency group="antlr" version="2.7.5" /> <dependency group="regexp" version="1.3" /> <dependency group="commons-beanutils" version="1.7.0" /> </dependencies> <echo message="Done" /> </sequential> </macrodef> <!-- ****************************************************************** --> <!-- ** Compile everything. ** --> <!-- ****************************************************************** --> <target name="compile"> <echo message="Compiling everything..." /> <delete dir="../classes/org" /> <mkdir dir="../classes/org" /> <javac srcdir="." destdir="../classes" debug="true" debuglevel="lines,vars,source"> <classpath refid="runtime_classpath" /> <classpath refid="compiletime_classpath" /> </javac> <echo message="Done" /> </target> <!-- ****************************************************************** --> <!-- ** Run CheckStyle. ** --> <!-- ****************************************************************** --> <target name="checkstyle"> <echo message="Performing CheckStyle analysis using rules file checkstyle.xml..." /> <taskdef resource="checkstyletask.properties"> <classpath refid="runtime_classpath" /> <classpath refid="compiletime_classpath" /> </taskdef> <checkstyle config="checkstyle.xml" failOnViolation="false"> <classpath refid="runtime_classpath" /> <classpath refid="compiletime_classpath" /> <fileset dir="." includes="**/*.java" /> <formatter type="xml" toFile="checkstyle_results.xml" /> </checkstyle> <echo message="Done (results saved in WEB-INF/src/checkstyle_results.xml" /> </target> <!-- ****************************************************************** --> <!-- ** Make javadocs. ** --> <!-- ****************************************************************** --> <target name="javadocs"> <echo message="Making Javadocs..." /> <delete dir="${javadocs}" /> <mkdir dir="${javadocs}" /> <javadoc sourcepath="${basedir}" overview="${basedir}/javadoc_overview.htm" destdir="${javadocs}" packagenames="*" author="true" private="true" version="true" encoding="iso-8859-1" windowtitle="${ant.project.name} API Documentation" doctitle="<h1>${ant.project.name}<br>Version ${project_version}</h1>" bottom="Copyright © 2005 Frank W. Zammetti"> <classpath refid="runtime_classpath" /> <classpath refid="compiletime_classpath" /> </javadoc> <echo message="Done" /> </target> <!-- ****************************************************************** --> <!-- ** This target builds our distribution file. Note that you ** --> <!-- ** have executed the default target right before this. ** --> <!-- ****************************************************************** --> <target name="distro"> <echo message="Making distros..." /> <delete file="${distro_dir}/ajaxchat_${project_version_filename}.zip" /> <jar destfile="${distro_dir}/ajaxchat.war" basedir="../" /> <zip destfile="${distro_dir}/ajaxchat_${project_version_filename}.zip" basedir="${distro_dir}"> <include name="ajaxchat.zip" /> </zip> <checksum file="${distro_dir}/ajaxchat_${project_version_filename}.zip" forceOverwrite="yes"/> <echo message="Done" /> </target> <!-- ****************************************************************** --> <!-- ** Clean up after a build (i.e., remove build-transient ** --> <!-- ** artifacts from the directory structure. This should ALWAYS ** --> <!-- ** be executed before checking in to source control. ** --> <!-- ****************************************************************** --> <target name="clean"> <echo message="Cleaning up..." /> <delete dir="${javadocs}" /> <delete file="checkstyle_results.xml" /> <delete file="build_log.xml" /> <echo message="Done" /> </target> </project> --- NEW FILE: checkstyle.xml --- <?xml version="1.0"?> <!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.2//EN" "http://www.puppycrawl.com/dtds/configuration_1_2.dtd"> <module name="Checker"> <!-- This configuration set is capable of running all the checks --> <!-- that CheckStyle is capable of, except for the header checks. --> <!-- Those that do not apply to JavaWebParts have been commented out. --> <!-- The following modules must have a Checker as their prent --> <!-- Javadocs comments --> <module name="PackageHtml" /> <!-- Miscellaneous --> <!--<module name="NewlineAtEndOfFile" />--> <module name="Translation" /> <!-- Duplicate code --> <!--<module name="StrictDuplicateCode" />--> <!-- The following modules must have a Treewalker as their parent --> <module name="TreeWalker"> <!-- Javadocs comments --> <module name="JavadocType" /> <module name="JavadocMethod" /> <!-- Naming conventions --> <module name="AbstractClassName" /> <module name="ConstantName" /> <module name="LocalFinalVariableName" /> <module name="LocalVariableName" /> <module name="MemberName" /> <module name="MethodName" /> <module name="PackageName" /> <module name="ParameterName" /> <module name="StaticVariableName" /> <module name="TypeName" /> <!-- Imports --> <module name="AvoidStarImport" /> <module name="IllegalImport" /> <module name="RedundantImport" /> <module name="UnusedImports" /> <!--<module name="ImportOrder" />--> <!-- Size violations --> <!--<module name="ExecutableStatementCount" />--> <module name="FileLength" /> <module name="LineLength" /> <module name="MethodLength"> <property name="max" value="200" /> <property name="countEmpty" value="false" /> </module> <module name="AnonInnerLength" /> <module name="ParameterNumber" /> <!-- Whitespace --> <!--<module name="EmptyForInitializerPad" />--> <!--<module name="EmptyForIteratorPad" />--> <module name="MethodParamPad" /> <module name="NoWhitespaceAfter" /> <module name="NoWhitespaceBefore" /> <!--<module name="OperatorWrap" />--> <module name="ParenPad" /> <!--<module name="TypecastParenPad" />--> <module name="TabCharacter" /> <!--<module name="WhitespaceAfter" />--> <!--<module name="WhitespaceAround" />--> <!-- Modifiers --> <module name="ModifierOrder" /> <!-- Block checks --> <module name="EmptyBlock" /> <module name="LeftCurly" /> <module name="NeedBraces" /> <module name="RightCurly" /> <module name="AvoidNestedBlocks" /> <!-- Coding --> <module name="ArrayTrailingComma" /> <module name="AvoidInlineConditionals" /> <module name="CovariantEquals" /> <module name="DoubleCheckedLocking" /> <module name="EmptyStatement" /> <module name="EqualsHashCode" /> <!--<module name="FinalLocalVariable" />--> <module name="HiddenField" /> <module name="IllegalInstantiation" /> <!--<module name="IllegalToken" />--> <module name="IllegalTokenText" /> <module name="InnerAssignment" /> <!--<module name="MagicNumber" />--> <module name="MissingSwitchDefault" /> <!--<module name="ModifiedControlVariable" />--> <module name="RedundantThrows" /> <module name="SimplifyBooleanExpression" /> <module name="SimplifyBooleanReturn" /> <module name="StringLiteralEquality" /> <!--<module name="NestedIfDepth" />--> <module name="NestedTryDepth" /> <module name="SuperClone" /> <module name="SuperFinalize" /> <module name="IllegalCatch" /> <module name="PackageDeclaration" /> <module name="JUnitTestCase" /> <module name="ReturnCount"> <property name="max" value="5"/> </module> <!--<module name="IllegalType" />--> <module name="DeclarationOrder" /> <module name="ParameterAssignment" /> <module name="ExplicitInitialization" /> <module name="DefaultComesLast" /> <!--<module name="MissingCtor" />--> <module name="FallThrough" /> <!--<module name="MultipleStringLiterals" />--> <module name="MultipleVariableDeclarations" /> <!--<module name="RequireThis" />--> <module name="UnnecessaryParentheses" /> <!-- Class design --> <module name="VisibilityModifier" /> <module name="FinalClass" /> <module name="InterfaceIsType" /> <module name="HideUtilityClassConstructor" /> <!--<module name="DesignForExtension" />--> <module name="MutableException" /> <!--<module name="ThrowsCount" /> --> <!-- Metrics --> <module name="BooleanExpressionComplexity"> <property name="max" value="10" /> </module> <module name="ClassDataAbstractionCoupling"> <property name="max" value="15" /> </module> <module name="ClassFanOutComplexity"> <property name="max" value="30" /> </module> <!--<module name="CyclomaticComplexity" />--> <!--<module name="NPathComplexity" />--> <!--<module name="JavaNCSS " />--> <!-- Miscellaneous --> <module name="TodoComment" /> <module name="UncommentedMain" /> <module name="UpperEll" /> <module name="ArrayTypeStyle" /> <!--<module name="FinalParameters" />--> <module name="DescendantToken" /> <!--<module name="Indentation" />--> <!--<module name="TrailingComment" /> --> </module> </module> --- NEW FILE: commons-logging.properties --- org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog --- NEW FILE: javadoc_overview.htm --- <body> AjaxChat overview. </body> --- NEW FILE: simplelog.properties --- org.apache.commons.logging.simplelog.defaultlog=debug |
From: <fza...@us...> - 2005-11-29 23:08:40
|
Update of /cvsroot/struts/ajaxchat In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020 Added Files: index.jsp lobby.jsp room.jsp Log Message: --- NEW FILE: index.jsp --- <%@ taglib prefix="html" uri="http://jakarta.apache.org/struts/tags-html" %> <%@ taglib prefix="bean" uri="http://jakarta.apache.org/struts/tags-bean" %> <%@ taglib prefix="logic" uri="http://jakarta.apache.org/struts/tags-logic" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <html> <head> <link rel="stylesheet" href="css/styles.css" type="text/css"> <title><fmt:message key="messages.appTitle" /></title> </head> <body class="cssMain" onLoad="LoginActionForm.username.focus();"> <div class="cssHeading"><fmt:message key="messages.appTitle" /></div> <hr/><br/> <fmt:message key="messages.welcomeBlock1" /> <br/><br/> <fmt:message key="messages.welcomeBlock2" /> <br/><br/> <logic:messagesPresent> <font color="#ff0000"> <html:messages id="error"> <bean:write name="error" /> </html:messages> </font> <br/><br/> </logic:messagesPresent> <html:form action="login"> <fmt:message key="labels.username" /> <html:text property="username" size="25" styleClass="cssUsernameInput" /> <html:submit styleClass="cssButton"> <fmt:message key="labels.loginButton" /> </html:submit> </html:form> </body> </html> --- NEW FILE: lobby.jsp --- <%@ taglib prefix="html" uri="http://jakarta.apache.org/struts/tags-html" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <html> <head> <link rel="stylesheet" href="css/styles.css" type="text/css"> <title><fmt:message key="messages.appTitle" /></title> <script> /** * This is the XMLHttpRequest object that is used to service this page * to update the stats (how many users are chatting in each room. */ xhrLobbyUpdateStats = null; /** * This is the timer that fires to continually update the room stats. */ timerLobbyUpdateStats = null; /** * This is the delay between AJAX requests to update room stats. */ lobbyUpdateStatsDelay = 2000; /** * When the user clicks the logout button, we need to immediately stop * firing AJAX events because if the timing is just right, the session could * be invalidated before another stats update is requested, which results * in an exception. So, this gets set to false when the logout button is * clicked, which stops the next request from being made. Note that there * is still a very small chance for the exception to occur, but the timing * would have to be pretty darned close! */ sendAJAXRequest = true; /** * This funtion is called on page load to initialize things. */ function init() { timerLobbyUpdateStats = setTimeout("lobbyUpdateStats()", 0); } // End init(). /** * This function is called as a result of the firing of the * timerLobbbyUpdateStats timer to make an AJAX request to get counts of * users chatting in each room. This happens continually as the user * sits in the lobby. */ function lobbyUpdateStats() { // Only fire a new event if a previous one has completed, or if the // XMLHttpRequest object is in an uninitialized state, or one has not // yet been instantiated. if (xhrLobbyUpdateStats == null || xhrLobbyUpdateStats.readyState == 0 || xhrLobbyUpdateStats.readyState == 4) { try { if (window.XMLHttpRequest){ xhrLobbyUpdateStats = new XMLHttpRequest(); } else { xhrLobbyUpdateStats = new ActiveXObject('Microsoft.XMLHTTP'); } xhrLobbyUpdateStats.onreadystatechange = lobbyUpdateStatsHandler; target = "<html:rewrite action="ajaxLobbyUpdateStats" />"; if (sendAJAXRequest) { xhrLobbyUpdateStats.open("post", target, true); xhrLobbyUpdateStats.send(null); } } catch(e) { alert("Error in lobbyUpdateStats() - " + e.message); } } // Restart the timer no matter what happened above. timerLobbyUpdateStats = setTimeout("lobbyUpdateStats()", lobbyUpdateStatsDelay); } // End lobbyUpdateStats(). /** * This is the AJAX callback handler that updates the display. */ function lobbyUpdateStatsHandler() { if (xhrLobbyUpdateStats.readyState == 4) { if (xhrLobbyUpdateStats.status == 200) { // Get the returned XML and parse it, creating our HTML for display. newHTML = ""; msgDOM = xhrLobbyUpdateStats.responseXML; root = msgDOM.getElementsByTagName("rooms")[0]; rooms = root.getElementsByTagName("room"); for (i = 0; i < rooms.length; i++) { room = rooms[i]; roomName = room.getAttribute("name"); users = room.getAttribute("users"); url = "<a href=\"<c:url value="joinRoom.do?name=" />"; newHTML += url + escape(roomName) + "\">" + roomName + "</a>"; newHTML += " (" + users + ")<br/>"; } // Update the display. objRoomList = document.getElementById("roomList"); objRoomList.innerHTML = newHTML; } else { alert("Error in lobbyUpdateStatsHandler() - " + xhrLobbyUpdateStats.status); } } } // End lobbyUpdateStatsHandler(). </script> </head> <body class="cssMain" onLoad="init();"> <div class="cssHeading"><fmt:message key="messages.appTitle" /></div> <hr/><br/> <fmt:message key="messages.inTheLobby" /> <br/><br/> <div id="roomList"> <c:forEach var="roomName" items="${LobbyActionForm.rooms}"> <a href="<c:url value="joinRoom.do"> <c:param name="name" value="${roomName}" /></c:url>"> <c:out value="${roomName}" /> </a> <br/> </c:forEach> </div> <br/> <fmt:message key="messages.joinRoomInstructions" /> <br/><br/><br/> <input type="button" class="cssButton" onClick="sendAJAXRequest=false;window.location='<html:rewrite action="logout" />';" value="<fmt:message key="labels.logoutButton" />" /> </body> </html> --- NEW FILE: room.jsp --- <%@ taglib prefix="html" uri="http://jakarta.apache.org/struts/tags-html" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %> <%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %> <html> <head> <link rel="stylesheet" href="css/styles.css" type="text/css"> <title><fmt:message key="messages.appTitle" /></title> <script> /** * This is the size of the font in the chat scroll. It is adjustable * between 8 and 48 using the magnification icons. Note that affects both * your text and other users' text together. */ scrollChatFontSize = 12; /** * This variable stores the last HTML that was inserted into the userList * div. When we get the list of users in the room, we compare this value * to the new HTML we construct. If they are identical, we DO NOT update * the div. This is to alleviate flickering that happens in Firefox priod * to v1.5 (supposed to have been fixed in 1.5, I have not tested it). */ oldUserListHTML = ""; /** * These variables are references to the XMLHttpRequest objects we'll use * to service our continual AJAX events. */ xhrListUsersInRoom = null; xhrGetMessages = null; /** * These variables are references to the Javascript timers that fire our * continuous AJAX events. */ timerListUsersInRoom = null; timerGetMessages = null; /** * These variables define how many milliseconds will elapse before each * of the continuous AJAX requests fire. In other words, the list of users * timer will fire every second to send an AJAX request to update the list. * Note that this DOES NOT mean an AJAX request will be sent... if one is * already in progress, that iteration is effectively skipped. This means * that a sever network problem could cause a new event to never fire (hey, * that would make a good enhancement... for each skipped request, see how * long it's been since the last successful one, and if it's been more than * a few seconds, allow the new event to fire anyway). */ listUsersInRoomDelay = 2000; getMessagesDelay = 1000; /** * This function initializes everything. Basically this amounts to kicking * off the user list and chat history scroll retrieval timers so that we * have two AJAX events constantly firing, one get update the list of users * in the room, the other to update the list of messages posted to the room. */ function init() { // Start the timers that fires the AJAX event to update the list of // users in the room and the chat history scroll. timerListUsersInRoom = setTimeout("listUsersInRoom()", 0); timerGetMessages = setTimeout("getMessages()", 0); } // End init(). /** * This function sends the AJAX request to get the list of users currently * in the room. */ function listUsersInRoom() { // Only fire a new event if a previous one has completed, or if the // XMLHttpRequest object is in an uninitialized state, or one has not // yet been instantiated. if (xhrListUsersInRoom == null || xhrListUsersInRoom.readyState == 0 || xhrListUsersInRoom.readyState == 4) { try { if (window.XMLHttpRequest){ xhrListUsersInRoom = new XMLHttpRequest(); } else { xhrListUsersInRoom = new ActiveXObject('Microsoft.XMLHTTP'); } xhrListUsersInRoom.onreadystatechange = listUsersInRoomHandler; target = "<html:rewrite action="ajaxListUsersInRoom" />"; xhrListUsersInRoom.open("post", target, true); xhrListUsersInRoom.send(null); } catch(e) { alert("Error in listUsersInRoom() - " + e.message); } } // Restart the timer no matter what happened above. timerListUsersInRoom = setTimeout("listUsersInRoom()", listUsersInRoomDelay); } // End listUsersInRoom(). /** * This function handles state changes for the listUsersInRoom AJAX request. */ function listUsersInRoomHandler() { if (xhrListUsersInRoom.readyState == 4) { if (xhrListUsersInRoom.status == 200) { // Get the returned XML and parse it, creating our HTML for display. newHTML = ""; msgDOM = xhrListUsersInRoom.responseXML; root = msgDOM.getElementsByTagName("users")[0]; users = root.getElementsByTagName("user"); for (i = 0; i < users.length; i++) { newHTML += users[i].getAttribute("name") + "<br/>"; } // Update the display. if (oldUserListHTML != newHTML) { oldUserListHTML = newHTML; document.getElementById("userList").innerHTML = newHTML; } } else { alert("Error in listUsersInRoomHandler() - " + xhrListUsersInRoom.status); } } } // End listUsersInRoomHandler(). /** * This function sends the AJAX request to get the messages to be shown * in the history scroll. With each such request, we record the index that * was last requested (which will be set to the index of the highest * message we get back), so that each subsequent request effectively only * gets new messages. */ function getMessages() { // Only fire a new event if a previous one has completed, or if the // XMLHttpRequest object is in an uninitialized state, or one has not // yet been instantiated. if (xhrGetMessages == null || xhrGetMessages.readyState == 0 || xhrGetMessages.readyState == 4) { try { if (window.XMLHttpRequest){ xhrGetMessages = new XMLHttpRequest(); } else { xhrGetMessages = new ActiveXObject('Microsoft.XMLHTTP'); } xhrGetMessages.onreadystatechange = getMessagesHandler; target = "<html:rewrite action="ajaxGetMessages" />"; xhrGetMessages.open("post", target, true); xhrGetMessages.send(null); } catch(e) { alert("Error in getMessages() - " + e.message); } } // Restart the timer no matter what happened above. timerGetMessages = setTimeout("getMessages()", getMessagesDelay); } // End getMessages(). /** * This function handles state changes for the listUsersInRoom AJAX request. */ function getMessagesHandler() { if (xhrGetMessages.readyState == 4) { if (xhrGetMessages.status == 200) { // Get the returned XML and parse it, creating our HTML for display. newHTML = ""; msgDOM = xhrGetMessages.responseXML; root = msgDOM.getElementsByTagName("messages")[0]; messages = root.getElementsByTagName("message"); for (i = 0; i < messages.length; i++) { message = messages[i]; postedBy = message.getElementsByTagName("postedBy")[0].firstChild.nodeValue; postedDateTime = message.getElementsByTagName( "postedDateTime")[0].firstChild.nodeValue; msgText = message.getElementsByTagName( "msgText")[0].firstChild.nodeValue; txtColor = ""; if (postedBy == "<c:out value="${user.username}" />") { txtColor = document.getElementById("yourColor").value; } else { txtColor = document.getElementById("theirColor").value; } newHTML += "<font color=\"" + txtColor + "\">" + "[" + postedDateTime + "] " + postedBy + ": " + msgText + "</font><br/>"; } // Update the display. Note that the first time through we want to // completely overwrite what's there (just ), all other times // we want to add on to ehat's there. This is done to avoid the // borders collapsing and there being a minor visual glitch. objChatScroll = document.getElementById("chatScroll"); if (newHTML != "") { if (objChatScroll.innerHTML == " ") { objChatScroll.innerHTML = newHTML; } else { objChatScroll.innerHTML += newHTML; } } // Lastly, always scroll to the bottom objChatScroll.scrollTop = 1000000; } else { alert("Error in getMessagesHandler() - " + xhrGetMessages.status); } } } // End getMessagesHandler(). /** * This function is called to leave the room. */ function leaveRoom() { window.location = "<html:rewrite action="leaveRoom" />"; } // End leaveRoom(). /** * This function is called to clear the chat history scroll. */ function clearHistory() { document.getElementById("chatScroll").innerHTML = " "; } // End clearHistory(). /** * This function trims whitespace from both ends of a string. */ function fullTrim(inString) { return (inString.replace(/^\s*(.*\S|.*)\s*$/, '$1')); } // End fullTrim(). /** * This function is called to post a message to the room. Note that there * is no AJAX callback handler... since the message scroll will be updated * anyway, it's kind of redundant. It also means there will be potentially * a slight delay between a user submitting a message and it showing up, * but this is considered acceptable. */ function postMessage() { userInputText = document.getElementById("userInput"); if (fullTrim(userInputText.value) != "") { if (window.XMLHttpRequest){ xhrPostMessage = new XMLHttpRequest(); } else { xhrPostMessage = new ActiveXObject('Microsoft.XMLHTTP'); } try { target = "<html:rewrite action="ajaxPostMessage" />"; target += "?msgText=" + escape(userInputText.value); xhrPostMessage.open("post", target, true); xhrPostMessage.send(null); userInputText.value = ""; userInputText.focus(); } catch(e) { alert(e.message); } } } // End postMessage(). function increaseChatScrollFontSize() { cs = document.getElementById("chatScroll"); scrollChatFontSize = scrollChatFontSize + 2; if (scrollChatFontSize > 48) { scrollChatFontSize = 48; } cs.style.fontSize = scrollChatFontSize + "pt"; } function decreaseChatScrollFontSize() { cs = document.getElementById("chatScroll"); scrollChatFontSize = scrollChatFontSize - 2; if (scrollChatFontSize < 8) { scrollChatFontSize = 8; } cs.style.fontSize = scrollChatFontSize + "pt"; } </script> </head> <body onLoad="init();" class="cssMain"> <table align="center" border="1" bordercolor="#000000" width="100%" height="100%" cellpadding="4" cellspacing="0" class="cssRoomMainTable"> <!-- Header section --> <tr> <td colspan="2" class="cssRoomHeader" height="40"> <fmt:message key="messages.nowChattingIn" /> <c:out value="${roomName}" /> </td> </tr> <!-- Chat scroll section --> <tr> <td height="100%" valign="top"> <div id="chatScroll" class="cssRoomChatScroll" /> </td> <!-- User list section --> <td rowspan="3" width="200" align="top"> <div id="userList" class="cssRoomUserList" /> </td> </tr> <!-- User control section --> <tr> <td height="60" valign="middle" id="userControl" class="cssRoomUserControl"> <!-- Leave room button --> <input type="button" value="<fmt:message key="labels.leaveRoomButton" />" class="cssButton" onClick="leaveRoom();" /> <!-- Clear history button --> <input type="button" value="<fmt:message key="labels.clearHistoryButton" />" class="cssButton" onClick="clearHistory();" /> <!-- Increase/Decrease font size --> <fmt:message key="labels.fontSize" /> <img src="img/zoomUp.gif" align="absmiddle" alt="<fmt:message key="labels.increaseFontSize" />" onClick="increaseChatScrollFontSize();" onMouseOver="this.style.cursor='hand';" onMouseOut="this.style.cursor='';"> <img src="img/zoomDown.gif" align="absmiddle" alt="<fmt:message key="labels.decreaseFontSize" />" onClick="decreaseChatScrollFontSize()"; onMouseOver="this.style.cursor='hand';" onMouseOut="this.style.cursor='';"> <br/> <!-- Your color --> <fmt:message key="labels.yourColor" /> <select class="cssSelect" id="yourColor"> <%@ include file="/inc/color_options.inc" %> </select> <!-- Their color --> <fmt:message key="labels.theirColor" /> <select class="cssSelect" id="theirColor"> <%@ include file="/inc/color_options.inc" %> </select> </td> </tr> <!-- User input section --> <tr> <td height="70" valign="middle" class="cssRoomUserInput"> <textarea class="cssUserInput" id="userInput" onKeyUp="if(event.keyCode==13){postMessage();}"></textarea> <input type="button" class="cssButton" value="<fmt:message key="labels.sendButton" />" onClick="postMessage();" /> </td> </tr> </table> </body> </html> |
From: <fza...@us...> - 2005-11-29 23:08:40
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/dto In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src/org/apache/struts/apps/ajaxchat/dto Added Files: MessageDTO.java RoomDTO.java UserDTO.java package.html Log Message: --- NEW FILE: MessageDTO.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.dto; import java.lang.reflect.Field; import java.util.Date; /** * This class is a Data Transfer Object (DTO) that describes a Message. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public class MessageDTO { /** * Text of the message. */ private String text; /** * User who posted the message. */ private UserDTO postedBy; /** * Date and time the message was posted. */ private Date postedDateTime; /** * Accessor for text field. * * @return String Current value of text Field. */ public String getText() { return text; } // End getText(). /** * Mutator for text field. * * @param inText New value of text field. */ public void setText(String inText) { text = inText; } // End setText(). /** * Accessor for postedBy field. * * @return String Current value of postedBy Field. */ public UserDTO getPostedBy() { return postedBy; } // End getPostedBy(). /** * Mutator for postedBy field. * * @param inPostedBy New value of postedBy field. */ public void setPostedBy(UserDTO inPostedBy) { postedBy = inPostedBy; } // End setPostedBy(). /** * Accessor for postedDateTime field. * * @return String Current value of postedDateTime Field. */ public Date getPostedDateTime() { return postedDateTime; } // End getPostedDateTime(). /** * Mutator for postedDateTime field. * * @param inPostedDateTime New value of postedDateTime field. */ public void setPostedDateTime(Date inPostedDateTime) { postedDateTime = inPostedDateTime; } // End setPostedDateTime(). /** * Overriden toString method. * * @return A reflexively-built string representation of this bean. */ public String toString() { String str = null; StringBuffer sb = new StringBuffer(1000); sb.append("[" + super.toString() + "]={"); boolean firstPropertyDisplayed = false; try { Field[] fields = this.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (firstPropertyDisplayed) { sb.append(", "); } else { firstPropertyDisplayed = true; } sb.append(fields[i].getName() + "=" + fields[i].get(this)); } sb.append("}"); str = sb.toString().trim(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } return str; } // End toString(). } // End class. --- NEW FILE: RoomDTO.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.dto; import java.lang.reflect.Field; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.Vector; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.apps.ajaxchat.AjaxChatConfig; /** * This class is a Data Transfer Object (DTO) that describes a Room. Note that * a few of the methods here do just a tad more than I would generally like in * a DAO, but the architecture made sense this way, so I went with it. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public class RoomDTO { /** * Log instance. */ private static Log log = LogFactory.getLog(RoomDTO.class); /** * The name of the room. */ private String name; /** * The list of users currently chatting in the room. */ private Vector users = new Vector(); /** * The list of messages in the room. */ private Vector messages = new Vector(); /** * Constructor. */ public RoomDTO() { } // End constructor. /** * Constructor. * * @param inName The name of the room being instantiated. */ public RoomDTO(String inName) { name = inName; } // End constructor. /** * Return the name of the room. * * @return String Current value of name Field. */ public String getName() { return name; } // End getName(). /** * Set the name of the room. * * @param inName The name of the room. */ public void setName(String inName) { name = inName; } // End setName(). /** * Return a list of all users chatting in the room. * * @return The list of users chatting in the room. */ public Vector getUserList() { return users; } // End getUserList(). /** * Adds a user to the list of users chatting in the room. The user WILL NOT * be added if they are already in the collection, which should deal with * the user clicking the Refresh button on their browser. * * @param inUser The user to add to the list of users chatting in the room. */ public void addUser(UserDTO inUser) { log.info("RoomDTO addUser()..."); boolean userAlreadyInRoom = false; for (Iterator it = users.iterator(); it.hasNext();) { UserDTO user = (UserDTO)it.next(); if (user.getUsername().equalsIgnoreCase(inUser.getUsername())) { userAlreadyInRoom = true; } } if (!userAlreadyInRoom) { log.info("Adding user to room: " + inUser); users.add(inUser); Collections.sort(users); } log.info("User added to room"); } // End addUser(). /** * Removes a user from the list of users chatting in the room. * * @param inUser The user to remove. */ public void removeUser(UserDTO inUser) { log.info("RoomDTO removeUser()..."); // Scan through all users until we find the one with the username of the // user passed in and remove the user from the list. String usernameToRemove = inUser.getUsername(); int i = 0; int indexToRemove = -1; for (Iterator it = users.iterator(); it.hasNext();) { UserDTO user = (UserDTO)it.next(); if (user.getUsername().equalsIgnoreCase(usernameToRemove)) { log.info("Found " + usernameToRemove + ", removing..."); indexToRemove = i; } i++; } if (indexToRemove != -1) { users.remove(indexToRemove); log.info(usernameToRemove + " removed"); } log.info("RoomDTO removeUser() Done"); } // End removeUser(). /** * This method returns all messages after the given datetime. * * @param inDateTime The Datetime of from which all subsequent messages * will be returned. * @return List of messages. */ public Vector getMessages(Date inDateTime) { log.info("RoomDTO getMessages()..."); // Scan through the list of messages for the room and find any that were // posted after the given datetime, add those to a list to return. Vector al = new Vector(); for (Iterator it = messages.iterator(); it.hasNext();) { MessageDTO message = (MessageDTO)it.next(); if (message.getPostedDateTime().after(inDateTime)) { log.info("Returning message : " + message); al.add(message); } } return al; } // End getMessages(). /** * Posts a message to the room. * * @param inMessage A MessageDTO instance containing all the necessary * details for the message being posted. */ public void postMessage(MessageDTO inMessage) { if (messages.size() > AjaxChatConfig.getMaxMessages()) { messages.clear(); } messages.add(inMessage); } // End addMessage(). /** * Overriden toString method. * * @return A reflexively-built string representation of this bean. */ public String toString() { String str = null; StringBuffer sb = new StringBuffer(1000); sb.append("[" + super.toString() + "]={"); boolean firstPropertyDisplayed = false; try { Field[] fields = this.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (firstPropertyDisplayed) { sb.append(", "); } else { firstPropertyDisplayed = true; } sb.append(fields[i].getName() + "=" + fields[i].get(this)); } sb.append("}"); str = sb.toString().trim(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } return str; } // End toString(). } // End class. --- NEW FILE: UserDTO.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.dto; import java.lang.reflect.Field; /** * This class is a Data Transfer Object (DTO) that describes a User. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public class UserDTO implements Comparable { /** * Username of the user. */ private String username; /** * Constructor. * * @param inUsername Username for this user. */ public UserDTO(String inUsername) { username = inUsername; } // End constructor. /** * Accessor for username field. * * @return String Current value of username Field. */ public String getUsername() { return username; } // End getUsername(). /** * Mutator for username field. * * @param inUsername New value of username field. */ public void setUsername(String inUsername) { username = inUsername; } // End setUsername(). /** * Used to sort the list of users in the room when a new user joins. * * @param o UserDTO object to compare to. * @return Typical return val of compareTo() method of Comparable interface. */ public int compareTo(Object o) { return this.username.compareTo(((UserDTO)o).getUsername()); } // End compareTo(). /** * Overriden toString method. * * @return A reflexively-built string representation of this bean. */ public String toString() { String str = null; StringBuffer sb = new StringBuffer(1000); sb.append("[" + super.toString() + "]={"); boolean firstPropertyDisplayed = false; try { Field[] fields = this.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (firstPropertyDisplayed) { sb.append(", "); } else { firstPropertyDisplayed = true; } sb.append(fields[i].getName() + "=" + fields[i].get(this)); } sb.append("}"); str = sb.toString().trim(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } return str; } // End toString(). } // End class. --- NEW FILE: package.html --- <body> The org.apache.struts.apps.ajaxchat.dto package contains the Data Transfer Objects (DTO) that are used to pass information around within the AjaxChat application. </body> |
From: <fza...@us...> - 2005-11-29 23:08:40
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/listener In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src/org/apache/struts/apps/ajaxchat/listener Added Files: ContextListener.java SessionListener.java package.html Log Message: --- NEW FILE: ContextListener.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.listener; import java.io.InputStream; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; /** * This ContextListener performs some simple initialization of the application. * Namely, it gets a stream on our rooms configuration file and passes it * along to the DAO's init() method so it can be read in. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public class ContextListener implements ServletContextListener { /** * Log instance. */ private static Log log = LogFactory.getLog(ContextListener.class); /** * Name of the config file, including context-relarive path. */ private static final String CONFIG_FILE = "/WEB-INF/rooms-config.xml"; /** * Execute at app startup. * * @param event ServletContextEvent. */ public void contextInitialized(ServletContextEvent event) { log.info("ContextListener contextInitialized()..."); // Initialize DAO. AjaxChatDAO dao = AjaxChatDAO.getInstance(); // Get a stream on the config file and initialize the DAO so we'll have // some rooms to chat in. ServletContext servletContext = event.getServletContext(); InputStream isConfigFile = servletContext.getResourceAsStream(CONFIG_FILE); dao.init(isConfigFile); log.info("ContextListener Done"); } // End contextInitialized(); /** * Execute at app shutdown. * * @param event ServletContextEvent. */ public void contextDestroyed(ServletContextEvent event) { } // End contextDestroyed(). } // Ebd class. --- NEW FILE: SessionListener.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.listener; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; /** * This SessionListener serves one essential purpose: when a session expires, * either from a timeout or a call to invalidate() during logoff, the user * has to be removed from any room they are in. This should be redundant under * normal circumstances as when the user leaves a room they are removed from it * obviously, and to log off they must leave the room and return to the lobby. * But it a timeout occurs, this takes care of the user otherwise lingering. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public class SessionListener implements HttpSessionListener { /** * Log instance. */ private static Log log = LogFactory.getLog(SessionListener.class); /** * Unregistering the session when it is destroyed. * * @param event HttpSessionEvent. */ public void sessionCreated(HttpSessionEvent event) { } // End sessionCreated(). /** * Unregistering the session when it is destroyed. * * @param event HttpSessionEvent. */ public void sessionDestroyed(HttpSessionEvent event) { log.info("SessionListener sessionDestroyed()..."); // Get the user from session, if present, and remove them from all rooms. HttpSession session = event.getSession(); AjaxChatDAO dao = AjaxChatDAO.getInstance(); UserDTO user = (UserDTO)session.getAttribute("user"); if (user != null) { dao.removeUserFromAllRooms(user); } log.info("SessionListener sessionDestroyed() Done"); } // End sessionDestroyed(). } // Ebd class. --- NEW FILE: package.html --- <body> The org.apache.struts.apps.ajaxchat.listener package contains listeners needed by the AjaxChat application, including context listeners and session listeners. </body> |
From: <fza...@us...> - 2005-11-29 23:08:40
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src/org/apache/struts/apps/ajaxchat Added Files: AjaxChatConfig.java package.html Log Message: --- NEW FILE: AjaxChatConfig.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat; import java.lang.reflect.Field; /** * This class stores static application configuration information read in from * the app-config.xml file at startup. It is then accessible to all classes * that need it. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public class AjaxChatConfig { /** * The maximum number of messages to keep in the messages collection in * any given room. */ private static int maxMessages; /** * Constructor. */ public AjaxChatConfig() { } // End constructor. /** * Return the maxMessages field. * * @return Maximum number of messages to keep in the messages collection in * any given room. */ public static int getMaxMessages() { return maxMessages; } // End getMaxMessages(). /** * Set the maxMessages field. * * @param inMaxMessages New value of the maxMessages field. */ public void setMaxMessages(int inMaxMessages) { maxMessages = inMaxMessages; } // End setMaxMessages(). /** * Overriden toString method. * * @return A reflexively-built string representation of this bean. */ public String toString() { String str = null; StringBuffer sb = new StringBuffer(1000); sb.append("[" + super.toString() + "]={"); boolean firstPropertyDisplayed = false; try { Field[] fields = this.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (firstPropertyDisplayed) { sb.append(", "); } else { firstPropertyDisplayed = true; } sb.append(fields[i].getName() + "=" + fields[i].get(this)); } sb.append("}"); str = sb.toString().trim(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } return str; } // End toString(). } // End class. --- NEW FILE: package.html --- <body> The org.apache.struts.apps.ajaxchat.ajaxchat package contains general-purpose classes for the AjaxChat application, including the AjaxChatConfig class which holds static application configuration information. </body> |
From: <fza...@us...> - 2005-11-29 23:08:39
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/actionform In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src/org/apache/struts/apps/ajaxchat/actionform Added Files: LobbyActionForm.java package.html Log Message: --- NEW FILE: LobbyActionForm.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.actionform; import java.lang.reflect.Field; import java.util.Vector; import org.apache.struts.action.ActionForm; /** * ActionForm for the lobby screen. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class LobbyActionForm extends ActionForm { /** * The name of the room user clicks on. */ private String name = ""; /** * List of available rooms. */ private Vector rooms = new Vector(); /** * Accessor for name field. * * @return String Current value of name Field. */ public String getName() { return name; } // End getName(). /** * Mutator for name field. * * @param inName New value of name field. */ public void setName(String inName) { name = inName; } // End setName(). /** * Accessor for rooms field. * * @return Vector List of room. */ public Vector getRooms() { return rooms; } // End getRooms(). /** * Mutator for rooms field. * * @param inRooms New value of rooms field. */ public void setRooms(Vector inRooms) { rooms = inRooms; } // End setRooms(). /** * Overriden toString method. * * @return A reflexively-built string representation of this bean. */ public String toString() { String str = null; StringBuffer sb = new StringBuffer(1000); sb.append("[" + super.toString() + "]={"); boolean firstPropertyDisplayed = false; try { Field[] fields = this.getClass().getDeclaredFields(); for (int i = 0; i < fields.length; i++) { if (firstPropertyDisplayed) { sb.append(", "); } else { firstPropertyDisplayed = true; } sb.append(fields[i].getName() + "=" + fields[i].get(this)); } sb.append("}"); str = sb.toString().trim(); } catch (IllegalAccessException iae) { iae.printStackTrace(); } return str; } // End toString(). } // End class. --- NEW FILE: package.html --- <body> The org.apache.struts.apps.ajaxchat.actionform package contains the Struts ActionForms (those that are not of type DynaActionForm and therefore defined in the struts-config.xml file) that are used by the AjaxChat application. </body> |
From: <fza...@us...> - 2005-11-29 23:08:39
|
Update of /cvsroot/struts/ajaxchat/img In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/img Added Files: buttonBG.gif textBG.gif zoomDown.gif zoomUp.gif Log Message: --- NEW FILE: buttonBG.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: textBG.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: zoomDown.gif --- (This appears to be a binary file; contents omitted.) --- NEW FILE: zoomUp.gif --- (This appears to be a binary file; contents omitted.) |
From: <fza...@us...> - 2005-11-29 23:08:39
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/lib In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/lib Added Files: commons-beanutils-1.7.0.jar commons-digester-1.7.jar commons-lang-2.1.jar commons-logging-1.0.4.jar javawebparts_core.jar javawebparts_listener.jar jstl.jar standard.jar struts-1.2.7.jar Log Message: --- NEW FILE: commons-beanutils-1.7.0.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: commons-digester-1.7.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: commons-lang-2.1.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: commons-logging-1.0.4.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: javawebparts_core.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: javawebparts_listener.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: jstl.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: standard.jar --- (This appears to be a binary file; contents omitted.) --- NEW FILE: struts-1.2.7.jar --- (This appears to be a binary file; contents omitted.) |
From: <fza...@us...> - 2005-11-29 23:08:38
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/action In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src/org/apache/struts/apps/ajaxchat/action Added Files: GetMessagesAction.java JoinRoomAction.java LeaveRoomAction.java ListUsersInRoomAction.java LobbyAction.java LobbyUpdateStatsAction.java LoginAction.java LogoutAction.java PostMessageAction.java package.html Log Message: --- NEW FILE: GetMessagesAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.Vector; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.MessageDTO; /** * This is a Struts Action that is called via AJAX request to get all messages * posted to the room the user is currently in since the last such request * for the user. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class GetMessagesAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(GetMessagesAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("GetMessagesAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Get the info from session we need. String roomName = (String)session.getAttribute("roomName"); Date lastDateTime = (Date)session.getAttribute("lastDateTime"); log.info("roomName = " + roomName); log.info("lastDateTime = " + lastDateTime); // If lastDateTime is null, this is the first request, so we want to // record the current datetime. if (lastDateTime == null) { lastDateTime = new Date(); } // Ask the DAO to get the messages posted subsequent to lastDateTime for // the applicable room. AjaxChatDAO dao = AjaxChatDAO.getInstance(); Vector messages = dao.getMessages(roomName, lastDateTime); // Now iterate over the collection of messages we got and construct our // XML. StringBuffer xmlOut = new StringBuffer(4096); xmlOut.append("<messages>"); for (Iterator it = messages.iterator(); it.hasNext();) { MessageDTO message = (MessageDTO)it.next(); xmlOut.append("<message>"); xmlOut.append("<postedBy>" + StringEscapeUtils.escapeXml(message.getPostedBy().getUsername()) + "</postedBy>"); xmlOut.append("<postedDateTime>" + new SimpleDateFormat().format(message.getPostedDateTime()) + "</postedDateTime>"); xmlOut.append("<msgText>" + StringEscapeUtils.escapeXml(message.getText()) + "</msgText>"); xmlOut.append("</message>"); lastDateTime = message.getPostedDateTime(); } xmlOut.append("</messages>"); // Lastly, we need to record the datetime of the last message retrieved // in session so that we know where we left off next time. session.setAttribute("lastDateTime", lastDateTime); // Write out XML. log.info(xmlOut); response.setContentType("text/xml"); PrintWriter out = response.getWriter(); out.println(xmlOut.toString()); out.flush(); log.info("GetMessagesAction execute() Done"); // Response fully formed, nowhere to forward to. return null; } } // End execute(). } // End class. --- NEW FILE: JoinRoomAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.apps.ajaxchat.actionform.LobbyActionForm; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; /** * This is a Struts Action that is called when the user clicks on a room while * in the lobby. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class JoinRoomAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(JoinRoomAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("JoinRoomAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Get the name of the room the user selected. LobbyActionForm form = (LobbyActionForm)inForm; String roomName = form.getName(); // Record the room in the users' session. session.setAttribute("roomName", roomName); // Add the user to the room. UserDTO user = (UserDTO)session.getAttribute("user"); AjaxChatDAO dao = AjaxChatDAO.getInstance(); dao.addUserToRoom(roomName, user); log.info("JoinRoomAction execute() Done"); return mapping.findForward("showRoom"); } } // End execute(). } // End class. --- NEW FILE: LeaveRoomAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; /** * This is a Struts Action that is called when the user clicks the Leave Room * button while chatting in a room. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class LeaveRoomAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(LeaveRoomAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("LeaveRoomAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Remove the user from the room they were in. UserDTO user = (UserDTO)session.getAttribute("user"); String roomName = (String)session.getAttribute("roomName"); AjaxChatDAO dao = AjaxChatDAO.getInstance(); dao.removeUserFromRoom(roomName, user); log.info("LeaveRoomAction execute() Done"); // Return to the lobby. return mapping.findForward("gotoLobby"); } } // End execute(). } // End class. --- NEW FILE: ListUsersInRoomAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import java.io.PrintWriter; import java.util.Iterator; import java.util.Vector; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; /** * This is a Struts Action that is called via AJAX request to retrieve the list * of users in the room the user is currently in. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class ListUsersInRoomAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(ListUsersInRoomAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("ListUsersInRoomAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // We'll need the name of the room to get a list for. String roomName = (String)request.getSession().getAttribute("roomName"); log.info("Getting user list for roomName = " + roomName); // Get user list and create a CSV list from it. AjaxChatDAO dao = AjaxChatDAO.getInstance(); Vector userList = dao.getUserList(roomName); log.info("userList = " + userList); StringBuffer xmlOut = new StringBuffer(1024); xmlOut.append("<users>"); for (Iterator it = userList.iterator(); it.hasNext();) { UserDTO user = (UserDTO)it.next(); xmlOut.append("<user name=\"" + StringEscapeUtils.escapeXml(user.getUsername()) + "\"/>"); } xmlOut.append("</users>"); // Write out XML to response. log.info(xmlOut); response.setContentType("text/xml"); PrintWriter out = response.getWriter(); out.println(xmlOut.toString()); out.flush(); log.info("ListUsersInRoomAction execute() Done"); // Response fully formed, nowhere to forward to. return null; } } // End execute(). } // End class. --- NEW FILE: LobbyAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.apps.ajaxchat.actionform.LobbyActionForm; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; /** * This is a Struts Action that shows the lobby screen. Note that it is called * as a result of a user logging in, as well as continually via AJAX while the * user is in the lobby to update the room statistics (i.e, how many users are * chatting in each room). * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class LobbyAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(LobbyAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("LobbyAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Get the list of rooms and add it to the ActionForm. AjaxChatDAO dao = AjaxChatDAO.getInstance(); LobbyActionForm form = (LobbyActionForm)inForm; form.setRooms(dao.getRoomList()); log.info("LobbyAction execute() Done"); return mapping.findForward("showLobby"); } } // End execute(). } // End class. --- NEW FILE: LobbyUpdateStatsAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import java.io.PrintWriter; import java.util.Iterator; import java.util.LinkedHashMap; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.apps.ajaxchat.actionform.LobbyActionForm; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; /** * This is a Struts Action that is called via AJAX event to update the stats * for each room (really just how many users are chatting in the room). It * really does more than that though... it actually updates the list of rooms * entirely. In effect, this does the same thing as LobbyAction does, except * that it handles an AJAX event where LobbyAction is used like a typical * Action is, including using an ActionForm, which is not used here. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class LobbyUpdateStatsAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(LobbyUpdateStatsAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("LobbyAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Get the list of rooms. AjaxChatDAO dao = AjaxChatDAO.getInstance(); LobbyActionForm form = (LobbyActionForm)inForm; LinkedHashMap roomList = dao.getRoomUserCounts(); // Construct our output XML. StringBuffer xmlOut = new StringBuffer(1024); xmlOut.append("<rooms>"); for (Iterator it = roomList.keySet().iterator(); it.hasNext();) { String roomName = (String)it.next(); Integer userCount = (Integer)roomList.get(roomName); xmlOut.append("<room name=\"" + StringEscapeUtils.escapeXml(roomName) + "\" " + "users=\"" + userCount + "\"/>"); } xmlOut.append("</rooms>"); // Write out XML to response. log.info(xmlOut); response.setContentType("text/xml"); PrintWriter out = response.getWriter(); out.println(xmlOut.toString()); out.flush(); log.info("LobbyUpdateStatsAction execute() Done"); return null; } } // End execute(). } // End class. --- NEW FILE: LoginAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; import org.apache.struts.apps.ajaxchat.filter.SessionCheckerFilter; /** * This is a Struts Action that is called when the user clicks the Login button * on the welcome screen. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class LoginAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(LoginAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("LoginAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Get the username the user entered. String username = (String)request.getParameter("username"); ActionForward af = null; if (session != null && session.getAttribute(SessionCheckerFilter.LOGGED_IN_FLAG) != null) { // User is already logged in, they probably hit refresh while in the // lobby, so go there now. log.info("User already logged in, going to lobby"); af = mapping.findForward("gotoLobby"); } else { if (username == null || username.equalsIgnoreCase("")) { // Username was not entered, so they can't come in. log.info("Username not entered"); ActionMessages msgs = new ActionMessages(); msgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("messages.usernameBlank")); saveErrors(request, msgs); af = mapping.findForward("fail"); } else { if (AjaxChatDAO.getInstance().isUsernameInUse(username)) { // The username is already in use, so they can't have it. ActionMessages msgs = new ActionMessages(); msgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("messages.usernameInUse")); saveErrors(request, msgs); af = mapping.findForward("fail"); } else { // Everything is OK, so create a new UserDTO and put it in session. log.info("Username entered"); UserDTO user = new UserDTO(username); session.setAttribute("user", user); session.setAttribute("isLoggedIn", "yes"); // Lastly, add this user to the list of logged on users. AjaxChatDAO.getInstance().logUserIn(user); af = mapping.findForward("gotoLobby"); } } } log.info("LoginAction execute() Done"); return af; } } // End execute(). } // End class. --- NEW FILE: LogoutAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; /** * This is a Struts Action that is called when the user clicks the Logout * button in the Lobby. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class LogoutAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(LogoutAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("LogoutAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Not much to do, just invalidate the session and log the user out as far // as our DAO goes. UserDTO user = (UserDTO)request.getSession().getAttribute("user"); AjaxChatDAO.getInstance().logUserOut(user); request.getSession().invalidate(); // Display a nice message for the user informing them they are logged out. ActionMessages msgs = new ActionMessages(); msgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("messages.loggedOut")); saveErrors(request, msgs); log.info("LogoutAction execute() Done"); return mapping.findForward("gotoWelcome"); } } // End execute(). } // End class. --- NEW FILE: PostMessageAction.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.action; import java.util.Date; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.Action; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.apps.ajaxchat.dao.AjaxChatDAO; import org.apache.struts.apps.ajaxchat.dto.MessageDTO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; import org.apache.struts.action.DynaActionForm; /** * This is a Struts Action that is called via AJAX request to post a message * to the room the user is currently in. * * @author <a href="mailto:fra...@pf...">Frank W. Zammetti</a>. */ public class PostMessageAction extends Action { /** * Log instance. */ private static Log log = LogFactory.getLog(PostMessageAction.class); /** * Execute. * * @param mapping ActionMapping. * @param inForm ActionForm. * @param request HttpServletRequest. * @param response HttpServletResponse. * @return ActionForward. * @throws Exception If anything goes wrong. */ public ActionForward execute(ActionMapping mapping, ActionForm inForm, HttpServletRequest request, HttpServletResponse response) throws Exception { log.info("PostMessageAction execute()..."); HttpSession session = request.getSession(); synchronized (session) { // Get the users' name, message text and room they are in. UserDTO user = (UserDTO)session.getAttribute("user"); String username = user.getUsername(); String roomName = (String)session.getAttribute("roomName"); DynaActionForm form = (DynaActionForm)inForm; String msgText = (String)form.get("msgText"); // Create a new MessageDTO and post it. MessageDTO message = new MessageDTO(); message.setPostedBy(user); message.setPostedDateTime(new Date()); message.setText(msgText); AjaxChatDAO dao = AjaxChatDAO.getInstance(); dao.postMessage(roomName, message); log.info("PostMessageAction execute() Done"); // There isn't actually anything to return from this function. return null; } } // End execute(). } // End class. --- NEW FILE: package.html --- <body> The org.apache.struts.apps.ajaxchat.action package contains the Struts Actions that make up the AjaxChat application. </body> |
From: <fza...@us...> - 2005-11-29 23:08:38
|
Update of /cvsroot/struts/ajaxchat/inc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/inc Added Files: color_options.inc Log Message: --- NEW FILE: color_options.inc --- <option value="#f0f8ff" style="color:#f0f8ff;">Alice Blue</option> <option value="#faebd7" style="color:#faebd7;">Antique White</option> <option value="#00ffff" style="color:#00ffff;">Aqua</option> <option value="#7fffd4" style="color:#7fffd4;">Aquamarine</option> <option value="#f0ffff" style="color:#f0ffff;">Azure</option> <option value="#f5f5dc" style="color:#f5f5dc;">Beige</option> <option value="#ffe4c4" style="color:#ffe4c4;">Bisque</option> <option value="#000000" style="color:#000000;" selected>Black</option> <option value="#ffebcd" style="color:#ffebcd;">Blanched Almond</option> <option value="#0000ff" style="color:#0000ff;">Blue</option> <option value="#8a2be2" style="color:#8a2be2;">Blue-Violet</option> <option value="#a52a2a" style="color:#a52a2a;">Brown</option> <option value="#deb887" style="color:#deb887;">Burlywood</option> <option value="#5f9ea0" style="color:#5f9ea0;">Cadet Blue</option> <option value="#7fff00" style="color:#7fff00;">Chartreuse</option> <option value="#d2691e" style="color:#d2691e;">Chocolate</option> <option value="#ff7f50" style="color:#ff7f50;">Coral</option> <option value="#6495ed" style="color:#6495ed;">Cornflower Blue</option> <option value="#fff8dc" style="color:#fff8dc;">Cornsilk</option> <option value="#00ffff" style="color:#00ffff;">Cyan</option> <option value="#00008b" style="color:#00008b;">Dark Blue</option> <option value="#008b8b" style="color:#008b8b;">Dark Cyan</option> <option value="#b8860b" style="color:#b8860b;">Dark Goldenrod</option> <option value="#a9a9a9" style="color:#a9a9a9;">Dark Gray</option> <option value="#006400" style="color:#006400;">Dark Green</option> <option value="#bdb76b" style="color:#bdb76b;">Dark Khaki</option> <option value="#8b008b" style="color:#8b008b;">Dark Magenta</option> <option value="#556b2f" style="color:#556b2f;">Dark Olive Green</option> <option value="#ff8c00" style="color:#ff8c00;">Dark Orange</option> <option value="#9932cc" style="color:#9932cc;">Dark Orchid</option> <option value="#8b0000" style="color:#8b0000;">Dark Red</option> <option value="#e9967a" style="color:#e9967a;">Dark Salmon</option> <option value="#8fbc8f" style="color:#8fbc8f;">Dark Sea Green</option> <option value="#483d8b" style="color:#483d8b;">Dark Slate Blue</option> <option value="#2f4f4f" style="color:#2f4f4f;">Dark Slate Gray</option> <option value="#00ced1" style="color:#00ced1;">Dark Turquoise</option> <option value="#9400d3" style="color:#9400d3;">Dark Violet</option> <option value="#ff1493" style="color:#ff1493;">Deep Pink</option> <option value="#00bfff" style="color:#00bfff;">Deep Sky Blue</option> <option value="#696969" style="color:#696969;">Dim Gray</option> <option value="#1e90ff" style="color:#1e90ff;">Dodger Blue</option> <option value="#b22222" style="color:#b22222;">Firebrick</option> <option value="#fffaf0" style="color:#fffaf0;">Floral White</option> <option value="#228b22" style="color:#228b22;">Forest Green</option> <option value="#ff00ff" style="color:#ff00ff;">Fuschia</option> <option value="#dcdcdc" style="color:#dcdcdc;">Gainsboro</option> <option value="#f8f8ff" style="color:#f8f8ff;">Ghost White</option> <option value="#ffd700" style="color:#ffd700;">Gold</option> <option value="#daa520" style="color:#daa520;">Goldenrod</option> <option value="#808080" style="color:#808080;">Gray</option> <option value="#008000" style="color:#008000;">Green</option> <option value="#adff2f" style="color:#adff2f;">Green-Yellow</option> <option value="#f0fff0" style="color:#f0fff0;">Honeydew</option> <option value="#ff69b4" style="color:#ff69b4;">Hot Pink</option> <option value="#cd5c5c" style="color:#cd5c5c;">Indian Red</option> <option value="#fffff0" style="color:#fffff0;">Ivory</option> <option value="#f0e68c" style="color:#f0e68c;">Khaki</option> <option value="#e6e6fa" style="color:#e6e6fa;">Lavender</option> <option value="#fff0f5" style="color:#fff0f5;">Lavender Blush</option> <option value="#7cfc00" style="color:#7cfc00;">Lawn Green</option> <option value="#fffacd" style="color:#fffacd;">Lemon Chiffon</option> <option value="#add8e6" style="color:#add8e6;">Light Blue</option> <option value="#f08080" style="color:#f08080;">Light Coral</option> <option value="#e0ffff" style="color:#e0ffff;">Light Cyan</option> <option value="#eedd82" style="color:#eedd82;">Light Goldenrod</option> <option value="#fafad2" style="color:#fafad2;">Light Goldenrod Yellow</option> <option value="#d3d3d3" style="color:#d3d3d3;">Light Gray</option> <option value="#90ee90" style="color:#90ee90;">Light Green</option> <option value="#ffb6c1" style="color:#ffb6c1;">Light Pink</option> <option value="#ffa07a" style="color:#ffa07a;">Light Salmon</option> <option value="#20b2aa" style="color:#20b2aa;">Light Sea Green</option> <option value="#87cefa" style="color:#87cefa;">Light Sky Blue</option> <option value="#8470ff" style="color:#8470ff;">Light Slate Blue</option> <option value="#778899" style="color:#778899;">Light Slate Gray</option> <option value="#b0c4de" style="color:#b0c4de;">Light Steel Blue</option> <option value="#ffffe0" style="color:#ffffe0;">Light Yellow</option> <option value="#00ff00" style="color:#00ff00;">Lime</option> <option value="#32cd32" style="color:#32cd32;">Lime Green</option> <option value="#faf0e6" style="color:#faf0e6;">Linen</option> <option value="#ff00ff" style="color:#ff00ff;">Magenta</option> <option value="#800000" style="color:#800000;">Maroon</option> <option value="#66cdaa" style="color:#66cdaa;">Medium Aquamarine</option> <option value="#0000cd" style="color:#0000cd;">Medium Blue</option> <option value="#ba55d3" style="color:#ba55d3;">Medium Orchid</option> <option value="#9370db" style="color:#9370db;">Medium Purple</option> <option value="#3cb371" style="color:#3cb371;">Medium Sea Green</option> <option value="#7b68ee" style="color:#7b68ee;">Medium Slate Blue</option> <option value="#00fa9a" style="color:#00fa9a;">Medium Spring Green</option> <option value="#48d1cc" style="color:#48d1cc;">Medium Turquoise</option> <option value="#c71585" style="color:#c71585;">Medium Violet-Red</option> <option value="#191970" style="color:#191970;">Midnight Blue</option> <option value="#f5fffa" style="color:#f5fffa;">Mint Cream</option> <option value="#e1e4e1" style="color:#e1e4e1;">Misty Rose</option> <option value="#ffe4b5" style="color:#ffe4b5;">Moccasin</option> <option value="#ffdead" style="color:#ffdead;">Navajo White</option> <option value="#000080" style="color:#000080;">Navy</option> <option value="#fdf5e6" style="color:#fdf5e6;">Old Lace</option> <option value="#808000" style="color:#808000;">Olive</option> <option value="#6b8e23" style="color:#6b8e23;">Olive Drab</option> <option value="#ffa500" style="color:#ffa500;">Orange</option> <option value="#ff4500" style="color:#ff4500;">Orange-Red</option> <option value="#da70d6" style="color:#da70d6;">Orchid</option> <option value="#eee8aa" style="color:#eee8aa;">Pale Goldenrod</option> <option value="#98fb98" style="color:#98fb98;">Pale Green</option> <option value="#afeeee" style="color:#afeeee;">Pale Turquoise</option> <option value="#db7093" style="color:#db7093;">Pale Violet-Red</option> <option value="#ffefd5" style="color:#ffefd5;">Papaya Whip</option> <option value="#ffdab9" style="color:#ffdab9;">Peach Puff</option> <option value="#cd853f" style="color:#cd853f;">Peru</option> <option value="#ffc0cb" style="color:#ffc0cb;">Pink</option> <option value="#dda0dd" style="color:#dda0dd;">Plum</option> <option value="#b0e0e6" style="color:#b0e0e6;">Powder Blue</option> <option value="#800080" style="color:#800080;">Purple</option> <option value="#ff0000" style="color:#ff0000;">Red</option> <option value="#bc8f8f" style="color:#bc8f8f;">Rosy Brown</option> <option value="#4169e1" style="color:#4169e1;">Royal Blue</option> <option value="#8b4513" style="color:#8b4513;">Saddle Brown</option> <option value="#fa8072" style="color:#fa8072;">Salmon</option> <option value="#f4a460" style="color:#f4a460;">Sandy Brown</option> <option value="#2e8b57" style="color:#2e8b57;">Sea Green</option> <option value="#fff5ee" style="color:#fff5ee;">Seashell</option> <option value="#a0522d" style="color:#a0522d;">Sienna</option> <option value="#c0c0c0" style="color:#c0c0c0;">Silver</option> <option value="#87ceeb" style="color:#87ceeb;">Sky Blue</option> <option value="#6a5acd" style="color:#6a5acd;">Slate Blue</option> <option value="#708090" style="color:#708090;">Slate Gray</option> <option value="#fffafa" style="color:#fffafa;">Snow</option> <option value="#00ff7f" style="color:#00ff7f;">Spring Green</option> <option value="#4682b4" style="color:#4682b4;">Steel Blue</option> <option value="#d2b48c" style="color:#d2b48c;">Tan</option> <option value="#008080" style="color:#008080;">Teal</option> <option value="#d8bfd8" style="color:#d8bfd8;">Thistle</option> <option value="#ff6347" style="color:#ff6347;">Tomato</option> <option value="#40e0d0" style="color:#40e0d0;">Turquoise</option> <option value="#ee82ee" style="color:#ee82ee;">Violet</option> <option value="#d02090" style="color:#d02090;">Violet-Red</option> <option value="#f5deb3" style="color:#f5deb3;">Wheat</option> <option value="#ffffff" style="color:#ffffff;">White</option> <option value="#f5f5f5" style="color:#f5f5f5;">White Smoke</option> <option value="#ffff00" style="color:#ffff00;">Yellow</option> <option value="#9acd32" style="color:#9acd32;">Yellow-Green</option> |
From: <fza...@us...> - 2005-11-29 23:08:38
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/filter In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src/org/apache/struts/apps/ajaxchat/filter Added Files: SessionCheckerFilter.java package.html Log Message: --- NEW FILE: SessionCheckerFilter.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.ActionMessage; import org.apache.struts.action.ActionMessages; import org.apache.struts.Globals; /** * This filter checks if the user is logged in and redirects to the welcome * page if they are not. The check is done by looking for the value in * session stored under the key named by the LOGGED_IN_FLAG field below. * Note that this filter ignores certain paths where the check does not apply. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public class SessionCheckerFilter implements Filter { /** * Logged in flag field key. */ public static final String LOGGED_IN_FLAG = "isLoggedIn"; /** * Log instance. */ private static Log log = LogFactory.getLog(SessionCheckerFilter.class); /** * Initialize. * * @param filterConfig The configuration information for this filter. * @throws ServletException ServletException. */ public void init(FilterConfig filterConfig) throws ServletException { } // End init(). /** * If no session exists for this request, and the requested path isnot * /login or /logout, redirect to the welcome page. * * @param request The current request object. * @param response The current response object. * @param filterChain The current filter chain. * @throws ServletException ServletException. * @throws IOException IOException. */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException { log.info("SessionCheckerFilter doFilter()..."); String path = ((HttpServletRequest)request).getServletPath(); log.info("path = " + path); if (path.indexOf("index") == -1 && path.indexOf("login") == -1 && path.indexOf("logout") == -1 && path.indexOf("css") == -1 && path.indexOf("gif") == -1) { // The requested path is NOT one of the ones we ignore, so check if // the user is logged in or not. HttpSession session = ((HttpServletRequest)request).getSession(); String isLoggedIn = (String)session.getAttribute(LOGGED_IN_FLAG); if (isLoggedIn == null) { // User *IS NOT* logged in, so redirect to welcome page. ActionMessages msgs = new ActionMessages(); msgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("messages.sessionTimedOut")); request.setAttribute(Globals.ERROR_KEY, msgs); log.info("SessionCheckerFilter Not logged in, " + "forwarding to welcome..."); request.getRequestDispatcher("/index.jsp").forward(request, response); return; } else { // User *IS* logged in, so request can continue as usual. log.info("SessionCheckerFilter Done (logged in)"); filterChain.doFilter(request, response); } } else { // Requested path is one of the ones we need to ignore, so request can // continue as usual, we don't care yet if the user is logged in or not. log.info("SessionCheckerFilter Done (ignored path " + path + ")"); filterChain.doFilter(request, response); } } // End doFilter(). /** * Destroy. */ public void destroy() { } // End destroy. } // End SessionCheckerFilter class. --- NEW FILE: package.html --- <body> The org.apache.struts.apps.ajaxchat.filter package contains servlet filters needed by the AjaxChat application. </body> |
From: <fza...@us...> - 2005-11-29 23:08:38
|
Update of /cvsroot/struts/ajaxchat/css In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/css Added Files: styles.css Log Message: --- NEW FILE: styles.css --- .cssHeading { font-family : verdana; font-size : 18pt; font-weight : bold; } .cssMain { font-family : verdana; font-size : 12pt; font-weight : bold; } .cssRoomMainTable { font-family : verdana; font-size : 12pt; font-weight : bold; background-color : #e0e0ff } .cssUsernameInput { font-family : verdana; font-size : 12pt; font-weight : bold; background : url("../img/textBG.gif"); } .cssUserInput { font-family : verdana; font-size : 12pt; font-weight : bold; width : 92%; background : url("../img/textBG.gif"); } .cssButton { font-family : verdana; font-size : 12pt; font-weight : bold; border-color : #ffffff; background-color : #c0c0c0; background-image : url("../img/buttonBG.gif"); color : #000000; } .cssSelect { font-family : verdana; font-weight : bold; font-size : 12pt; background-color : #f7f7f9; } .cssRoomHeader { font-family : verdana; font-size : 12pt; font-weight : bold; background-color : #e0e0ff; } .cssRoomUserControl { font-family : verdana; font-size : 12pt; font-weight : bold; background-color : #e0e0ff } .cssRoomUserList { font-family : verdana; font-size : 12pt; font-weight : bold; width : 200; height : 100%; overflow : scroll; padding-top : 4px; padding-left : 4px; background-color : #e0e0ff } .cssRoomUserInput { font-family : verdana; font-size : 12pt; font-weight : bold; background-color : #e0e0ff; } .cssRoomChatScroll { font-family : verdana; font-size : 12pt; font-weight : bold; width : 100%; height : 100%; overflow : scroll; background-color : #f7f7f9; } |
From: <fza...@us...> - 2005-11-29 23:08:38
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/dao In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/src/org/apache/struts/apps/ajaxchat/dao Added Files: AjaxChatDAO.java package.html Log Message: --- NEW FILE: AjaxChatDAO.java --- /* * Copyright 2005 Frank W. Zammetti * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.struts.apps.ajaxchat.dao; import java.io.InputStream; import java.io.IOException; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Vector; import org.apache.commons.digester.Digester; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.apps.ajaxchat.dto.MessageDTO; import org.apache.struts.apps.ajaxchat.dto.RoomDTO; import org.apache.struts.apps.ajaxchat.dto.UserDTO; import org.xml.sax.SAXException; /** * This Data Access Object (DAO) is really the heart and soul of the app. All * the real work is done here in terms of recording messages, dealing with * users and rooms and most everything else. * * @author <a href="mailto:fza...@om...">Frank W. Zammetti</a>. */ public final class AjaxChatDAO { /** * Log instance. */ private static Log log = LogFactory.getLog(AjaxChatDAO.class); /** * This class is a singleton, so here's the one and only instance. */ private static AjaxChatDAO instance; /** * Collection of RoomDTO objects. */ private LinkedHashMap rooms = new LinkedHashMap(); /** * Collection of UserDTO objects of currently logged in users. */ private Vector users = new Vector(); /** * Make sure instances of this class can't be created. */ private AjaxChatDAO() { } /** * Complete the singleton pattern. This method is the only way to get an * instance of this class. * * @return The one and only instance of this class. */ public static AjaxChatDAO getInstance() { log.info("AjaxChatDAO getInstance()..."); if (instance == null) { instance = new AjaxChatDAO(); instance.init(null); } log.info("AjaxChatDAO getInstance() Done"); return instance; } // End getInstance(). /** * Initialize. Read in room-list.xml file and create RoomDTOs for each * and add it to the collection of rooms. Note that the first time * getInstance() is called, we pass in null for the isConfigFile parameter, * and hence the config file is not read. Before this DAO can really be * used, init() must be called, handing it an InputStream to the config * file. This is done from ContextListener. * * @param isConfigFile InputStream to the config file. */ public synchronized void init(InputStream isConfigFile) { log.info("AjaxChatDAO init()..."); if (isConfigFile != null) { // Read in rooms config and create beans, hand off to DAO. Digester digester = new Digester(); digester.setValidating(false); digester.push(this); digester.addObjectCreate("rooms/room", "org.apache.struts.apps.ajaxchat.dto.RoomDTO"); digester.addSetProperties("rooms/room"); digester.addSetNext("rooms/room", "addRoom"); try { digester.parse(isConfigFile); log.info("***** Rooms = " + rooms); } catch (IOException ioe) { ioe.printStackTrace(); } catch (SAXException se) { se.printStackTrace(); } } log.info("AjaxChatDAO init() Done"); } // End init(). /** * Adds a room to the collection of rooms. * * @param inRoom The room to add. */ public synchronized void addRoom(RoomDTO inRoom) { log.info("AjaxChatDAO addRoom()..."); log.info("Adding room " + inRoom); rooms.put(inRoom.getName(), inRoom); log.info("AjaxChatDAO addRoom() Done"); } // End addRoom(). /** * Removes a room from the collection of rooms. * * @param inRoomName The namr of the room to remove. */ public synchronized void removeRoom(String inRoomName) { log.info("AjaxChatDAO removeRoom()..."); log.info("Removing room " + inRoomName); RoomDTO room = (RoomDTO)rooms.get(inRoomName); if (room.getUserList().size() == 0) { rooms.remove(inRoomName); log.info("AjaxChatDAO removeRoom() Done"); } else { log.info("AjaxChatDAO removeRoom() Room not removed because " + "there are users in it"); } } // End removeRoom(). /** * Add a message to the list of messages in the named room. * * @param inRoom The name of the room to post the message to. * @param inMessage The message to post. */ public synchronized void postMessage(String inRoom, MessageDTO inMessage) { log.info("AjaxChatDAO postMessage() : inRoom = " + inRoom + " - inMessage = " + inMessage); RoomDTO room = (RoomDTO)rooms.get(inRoom); room.postMessage(inMessage); } // End postMessage(). /** * Gets all messages in a named room newer than the specified datetime. * * @param inRoom The name of the room to get messages for. * @param inDateTime The date/time to start retrieval from. We will actually * get any message subsequent to this datetime. * @return List of messages for the named room. */ public synchronized Vector getMessages(String inRoom, Date inDateTime) { log.info("AjaxChatDAO getMessages() : inRoom = " + inRoom + " - inDateTime = " + inDateTime); RoomDTO room = (RoomDTO)rooms.get(inRoom); return room.getMessages(inDateTime); } // End getMessages(). /** * Returns a list of all rooms. Note that this returns the room name only, * it DOES NOT return a list of RoomDTOs. * * @return List of all rooms names. */ public synchronized Vector getRoomList() { log.info("AjaxChatDAO getRoomList()"); Vector roomList = new Vector(); for (Iterator it = rooms.keySet().iterator(); it.hasNext();) { roomList.add((String)it.next()); } log.info("AjaxChatDAO roomList = " + roomList); return roomList; } // End getRoomList(). /** * Returns a Map of rooms, keyed by room name, with the number of users * chatting in each as the value. * * @return List of all rooms and user counts. */ public synchronized LinkedHashMap getRoomUserCounts() { log.info("getRoomUserCounts getMessages()"); LinkedHashMap roomList = new LinkedHashMap(); for (Iterator it = rooms.keySet().iterator(); it.hasNext();) { String roomName = (String)it.next(); roomList.put(roomName, new Integer(((RoomDTO)rooms.get(roomName)).getUserList().size())); } log.info("getRoomUserCounts roomList = " + roomList); return roomList; } // End getRoomUserCounts(). /** * Returns a list of all users currently chatting in a given room. Note that * this returns the username only, it DOES NOT return a list of UserDTOs. * * @param inRoom The name of the room to get the user list for. * @return List of all usernames chatting in a named room. */ public synchronized Vector getUserList(String inRoom) { log.info("AjaxChatDAO getUserList() : inRoom = " + inRoom); Vector userList = null; RoomDTO room = (RoomDTO)rooms.get(inRoom); userList = room.getUserList(); log.info("AjaxChatDAO userList = " + userList); return userList; } // End getUserList(). /** * Adds a user to the specified room. * * @param inRoom The room to add to. * @param inUser The user to add. */ public synchronized void addUserToRoom(String inRoom, UserDTO inUser) { log.info("AjaxChatDAO addUserToRoom()..."); RoomDTO room = (RoomDTO)rooms.get(inRoom); room.addUser(inUser); log.info("AjaxChatDAO addUserToRoom() Done"); } // End addUserToRoom(). /** * Removes a user from the specified room. * * @param inRoom The room to add to. * @param inUser The user to remove. */ public synchronized void removeUserFromRoom(String inRoom, UserDTO inUser) { log.info("AjaxChatDAO removeUserFromRoom()..."); RoomDTO room = (RoomDTO)rooms.get(inRoom); room.removeUser(inUser); log.info("AjaxChatDAO removeUserFromRoom() Done"); } // End removeUserFromRoom(). /** * Removes a user from all rooms. This is kind of a safety net when a * users' session is destroyed. * * @param inUser The user to remove. */ public synchronized void removeUserFromAllRooms(UserDTO inUser) { log.info("AjaxChatDAO removeUserFromAllRooms()..."); for (Iterator it = rooms.keySet().iterator(); it.hasNext();) { String roomName = (String)it.next(); RoomDTO room = (RoomDTO)rooms.get(roomName); room.removeUser(inUser); } log.info("AjaxChatDAO removeUserFromAllRooms() Done"); } // End removeUserFromAllRooms(). /** * Adds a user to the list of logged on users. * * @param inUser The user to log in. */ public synchronized void logUserIn(UserDTO inUser) { log.info("AjaxChatDAO logUserIn()..."); users.add(inUser); log.info(inUser.getUsername() + " logged in"); } // End logUserIn(). /** * Removes a user from the list of logged on users. * * @param inUser The user to log out. */ public synchronized void logUserOut(UserDTO inUser) { log.info("AjaxChatDAO logUserOut()..."); String usernameToLogOut = inUser.getUsername(); int i = 0; int indexToRemove = -1; for (Iterator it = users.iterator(); it.hasNext();) { UserDTO user = (UserDTO)it.next(); if (usernameToLogOut.equalsIgnoreCase(user.getUsername())) { indexToRemove = i; } i++; } if (indexToRemove != -1) { users.remove(indexToRemove); log.info(usernameToLogOut + " logged out"); } } // End logUserIn(). /** * Checks to see if a given username is in use in any room. * * @param inUsername The name to check. * @return True if the name is in use, false if not. */ public synchronized boolean isUsernameInUse(String inUsername) { log.info("AjaxChatDAO isUsernameInUse()..."); boolean retVal = false; for (Iterator it = users.iterator(); it.hasNext();) { UserDTO user = (UserDTO)it.next(); if (inUsername.equalsIgnoreCase(user.getUsername())) { retVal = true; } } log.info("AjaxChatDAO isUsernameInUse() Done (" + retVal + ")"); return retVal; } // End isUsernameInUse(). } // End class. --- NEW FILE: package.html --- <body> The org.apache.struts.apps.ajaxchat.dao package contains the Data Access Object (DAO) where the majority of the work of the AjaxChat application happens, at least as far as the back-end goes. </body> |
From: <fza...@us...> - 2005-11-29 23:08:37
|
Update of /cvsroot/struts/ajaxchat/WEB-INF In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF Added Files: app-config.xml rooms-config.xml struts-config.xml web.xml Log Message: --- NEW FILE: app-config.xml --- <config> <!-- maxMessages is the maximum number of messages that will be stored in --> <!-- the messages collection of each room. Any time a message is posted --> <!-- to a room, the number of messages in the collection is checked --> <!-- against this value. If the count exceeds this value, the collection --> <!-- is cleared before the new messages is stored. This is just a --> <!-- memory-saving measure, and probably makes things a bit more --> <!-- efficient too. --> <maxMessages>250</maxMessages> </config> --- NEW FILE: rooms-config.xml --- <rooms> <room name="General Topics" /> <room name="Programming" /> <room name="Movies" /> <room name="Music" /> <room name="Television" /> </rooms> --- NEW FILE: struts-config.xml --- <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"> <struts-config> <!-- Form Beans --> <form-beans> <form-bean name="LobbyActionForm" type="org.apache.struts.apps.ajaxchat.actionform.LobbyActionForm" /> <form-bean name="LoginActionForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="username" type="java.lang.String" /> </form-bean> <form-bean name="ajaxPostMessageActionForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="msgText" type="java.lang.String" /> </form-bean> </form-beans> <!-- Mappings --> <action-mappings> <!-- ***** These are our normal Struts mappings. ***** --> <!-- Used when the user clicks Login on the welcome screen. --> <action path="/login" type="org.apache.struts.apps.ajaxchat.action.LoginAction" name="LoginActionForm" scope="request" validate="false"> <forward name="gotoLobby" path="/lobby.do" /> <forward name="fail" path="/index.jsp" /> </action> <!-- Used when the user clicks Logout on the lobby screen. --> <action path="/logout" type="org.apache.struts.apps.ajaxchat.action.LogoutAction"> <forward name="gotoWelcome" path="/index.jsp" /> </action> <!-- Used to show the lobby. --> <action path="/lobby" type="org.apache.struts.apps.ajaxchat.action.LobbyAction" name="LobbyActionForm" scope="request" validate="false"> <forward name="showLobby" path="/lobby.jsp" /> </action> <!-- Used when the user clicks on a room on the lobby screen. --> <action path="/joinRoom" type="org.apache.struts.apps.ajaxchat.action.JoinRoomAction" name="LobbyActionForm" scope="request" validate="false"> <forward name="showRoom" path="/room.jsp" /> </action> <!-- Used when the user clicks the Leave Room on the room screen. --> <action path="/leaveRoom" type="org.apache.struts.apps.ajaxchat.action.LeaveRoomAction"> <forward name="gotoLobby" path="/lobby.do" /> </action> <!-- ***** These are our Ajax-related mappings. ***** --> <!-- Used to list all the users in the room. --> <action path="/ajaxListUsersInRoom" type="org.apache.struts.apps.ajaxchat.action.ListUsersInRoomAction" /> <!-- Used to post a message to the room. --> <action path="/ajaxPostMessage" type="org.apache.struts.apps.ajaxchat.action.PostMessageAction" name="ajaxPostMessageActionForm" scope="request" validate="false" /> <!-- Used to get messages in the room. --> <action path="/ajaxGetMessages" type="org.apache.struts.apps.ajaxchat.action.GetMessagesAction" /> <!-- Used to get messages in the room. --> <action path="/ajaxLobbyUpdateStats" type="org.apache.struts.apps.ajaxchat.action.LobbyUpdateStatsAction" /> </action-mappings> <message-resources parameter="app_resources" /> </struts-config> --- NEW FILE: web.xml --- <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app> <display-name>Struts Apps- AjaxChat</display-name> <!-- Parameter for JSTL resource bundle usage. --> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> <param-value>app_resources</param-value> </context-param> <!-- Parameters related to application configuration. --> <context-param> <param-name>configFile</param-name> <param-value>/WEB-INF/app-config.xml</param-value> </context-param> <context-param> <param-name>configClass</param-name> <param-value>org.apache.struts.apps.ajaxchat.AjaxChatConfig</param-value> </context-param> <!-- The session checking filter. --> <filter> <filter-name>sessionCheckerFilter</filter-name> <filter-class>org.apache.struts.apps.ajaxchat.filter.SessionCheckerFilter</filter-class> </filter> <filter-mapping> <filter-name>sessionCheckerFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Context and Session listeners. --> <listener> <listener-class>javawebparts.listener.AppConfigContextListener</listener-class> </listener> <listener> <listener-class>org.apache.struts.apps.ajaxchat.listener.ContextListener</listener-class> </listener> <listener> <listener-class>org.apache.struts.apps.ajaxchat.listener.SessionListener</listener-class> </listener> <!-- Action Servlet. --> <servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>application</param-name> <param-value>app_resources</param-value> </init-param> <init-param> <param-name>debug</param-name> <param-value>5</param-value> </init-param> <init-param> <param-name>detail</param-name> <param-value>5</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- Session timeout config. --> <session-config> <session-timeout>1</session-timeout> </session-config> <!-- Welcome file config. --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
From: <fza...@us...> - 2005-11-29 23:08:37
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/classes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21020/WEB-INF/classes Added Files: app_resources_en.properties Log Message: --- NEW FILE: app_resources_en.properties --- messages.usernameBlank=There is a problem with the Username you entered - You must enter a Username messages.usernameContainsComma=There is a problem with the Username you entered - Username cannot contain commas (,) messages.usernameInUse=There is a problem with the Username you entered - That Username is already in use. Please choose another. messages.sessionTimedOut=Your session timed out (or you have not logged in yet). Please log in now. messages.appTitle=Struts Apps- AjaxChat messages.welcomeBlock1=Hello and welcome to the AjaxChat application from Struts Apps at SourceForge! This is meant to serve as an example of using AJAX with a Struts application. But, it is also meant to be a useful application on its own. messages.welcomeBlock2=Simply put, AjaxChat is a simple Struts-based chat application that uses AJAX. While you can use this for real, this is in NO WAY a robust chat app! For instance, the DAO used here uses synchronization when reading/writing messages in a room or the list of users in a room, so it is inherently not very scalable. Still, for small-scale use, it should be fine. You could always write a new DAO layer if you need something more robust. messages.inTheLobby=You are logged in and are now in the lobby. Here is the list of available chat rooms and how many users are currently chatting in each (the user count will be continually updated every two seconds): messages.joinRoomInstructions=Click a room to join it. messages.nowChattingIn=You are now chatting in messages.loggedOut=You have successfully logged out. Please feel free to log in again if you wish. labels.logoutButton=Log out labels.leaveRoomButton=Leave Room labels.clearHistoryButton=Clear History labels.sendButton=Send labels.username=Username: labels.loginButton=Login labels.fontSize=Font size: labels.yourColor=Your color: labels.theirColor=Their color: labels.increaseFontSize=Increase font size labels.decreaseFontSize=Decrease font size |
From: <fza...@us...> - 2005-11-29 23:06:24
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/listener In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20468/listener Log Message: Directory /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/listener added to the repository |
From: <fza...@us...> - 2005-11-29 23:06:23
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/dao In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20468/dao Log Message: Directory /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/dao added to the repository |
From: <fza...@us...> - 2005-11-29 23:06:23
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/dto In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20468/dto Log Message: Directory /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/dto added to the repository |
From: <fza...@us...> - 2005-11-29 23:06:23
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/filter In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20468/filter Log Message: Directory /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/filter added to the repository |
From: <fza...@us...> - 2005-11-29 23:06:23
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/actionform In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20468/actionform Log Message: Directory /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/actionform added to the repository |
From: <fza...@us...> - 2005-11-29 23:06:23
|
Update of /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/action In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20468/action Log Message: Directory /cvsroot/struts/ajaxchat/WEB-INF/src/org/apache/struts/apps/ajaxchat/action added to the repository |