You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by de...@apache.org on 2010/04/19 17:27:16 UTC

svn commit: r935623 [1/5] - in /activemq/trunk/activemq-web-demo/src/main/webapp: ./ js/

Author: dejanb
Date: Mon Apr 19 15:27:15 2010
New Revision: 935623

URL: http://svn.apache.org/viewvc?rev=935623&view=rev
Log:
https://issues.apache.org/activemq/browse/AMQ-1377 - Ajax client refactoring

Added:
    activemq/trunk/activemq-web-demo/src/main/webapp/js/amq.js
    activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_dojo_adapter.js
    activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_jquery_adapter.js   (with props)
    activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_prototype_adapter.js   (with props)
    activemq/trunk/activemq-web-demo/src/main/webapp/js/chat.js   (with props)
    activemq/trunk/activemq-web-demo/src/main/webapp/js/dojo.js
    activemq/trunk/activemq-web-demo/src/main/webapp/js/jquery-1.4.2.min.js
    activemq/trunk/activemq-web-demo/src/main/webapp/js/prototype.js   (with props)
Removed:
    activemq/trunk/activemq-web-demo/src/main/webapp/chat.js
    activemq/trunk/activemq-web-demo/src/main/webapp/js/scriptaculous.js
Modified:
    activemq/trunk/activemq-web-demo/src/main/webapp/chat.css
    activemq/trunk/activemq-web-demo/src/main/webapp/chat.html

Modified: activemq/trunk/activemq-web-demo/src/main/webapp/chat.css
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-web-demo/src/main/webapp/chat.css?rev=935623&r1=935622&r2=935623&view=diff
==============================================================================
--- activemq/trunk/activemq-web-demo/src/main/webapp/chat.css (original)
+++ activemq/trunk/activemq-web-demo/src/main/webapp/chat.css Mon Apr 19 15:27:15 2010
@@ -16,7 +16,7 @@
  */
 div#chatroom
 {
-  width: 41em;
+  width: 81em;
   background-color: #e0e0e0;
   border: 1px solid black; 
 }
@@ -24,8 +24,8 @@ div#chatroom
 div#chat
 {
   float: left;
-  width: 30em;
-  height: 20ex;
+  width: 60em;
+  height: 40ex;
   overflow: auto; 
   background-color: #f0f0f0;
   padding: 4px;
@@ -36,7 +36,7 @@ div#members
 {
   float: left;
   clear: right;
-  width: 10em;
+  width: 20em;
   border: 0px solid black; 
 }
 

Modified: activemq/trunk/activemq-web-demo/src/main/webapp/chat.html
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-web-demo/src/main/webapp/chat.html?rev=935623&r1=935622&r2=935623&view=diff
==============================================================================
--- activemq/trunk/activemq-web-demo/src/main/webapp/chat.html (original)
+++ activemq/trunk/activemq-web-demo/src/main/webapp/chat.html Mon Apr 19 15:27:15 2010
@@ -1,35 +1,114 @@
 <!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You 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.
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You 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.
 -->
-<html>
-<head>
-<title>Chat</title>
-<script type="text/javascript" src="amq/amq.js"></script>
-<script type="text/javascript">amq.uri='amq';</script>
-<script type="text/javascript" src="chat.js"></script>
-<link rel="stylesheet" href="chat.css" type="text/css">
-<link rel="stylesheet" href="style.css" type="text/css">
-</head>
-<body>
+ 
+ 
+ 
+ 
+ 
+ 
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
+ 
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
+<html> 
+<head> 
+    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> 
+    <title>Chat Example - ActiveMQ Web Demos</title> 
+    <link rel="stylesheet" href="chat.css" type="text/css">
+    <style type="text/css" media="screen"> 
+        @import url(/admin/styles/sorttable.css);
+        @import url(/admin/styles/type-settings.css);
+        @import url(/admin/styles/site.css);
+        @import url(/admin/styles/prettify.css);
+    </style>
+
+	<!--<script type="text/javascript" src="js/prototype.js"></script>-->
+	<!--<script type="text/javascript" src="js/amq_prototype_adapter.js"></script>-->
+	<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
+	<script type="text/javascript" src="js/amq_jquery_adapter.js"></script>
+
+	<script type="text/javascript" src="js/amq.js"></script>
+	<script type="text/javascript" src="js/chat.js"></script>
+	<script type="text/javascript">
+
+		// Note, normally you wouldn't just add an onload function in this
+		// manner. In fact, you typically want to fire this method on the
+		// document.onready event, however this type of functionality is verbose
+		// and best left to the domain of your favorite js library.
+		//
+		// For example, in jQuery the following onload would be replaced with:
+		// jQuery(function() {
+		//     org.activemq.Amq.init({ uri: 'amq' });
+		//     org.activemq.Chat.init();
+		// }
+		window.onload = function() {
+			org.activemq.Amq.init({ uri: 'amq', logging: true, timeout: 45 });
+			org.activemq.Chat.init();
+		};
+	</script>    
+    
+</head> 
+ 
+<body> 
+ 
+ 
+<div class="white_box"> 
+    <div class="header"> 
+        <div class="header_l"> 
+            <div class="header_r"> 
+            </div> 
+        </div> 
+    </div> 
+    <div class="content"> 
+        <div class="content_l"> 
+            <div class="content_r"> 
+ 
+                <div> 
+ 
+                    <!-- Banner --> 
+                    <div id="asf_logo"> 
+                        <div id="activemq_logo"> 
+                            <a style="float:left; width:280px;display:block;text-indent:-5000px;text-decoration:none;line-height:60px; margin-top:10px; margin-left:100px;"
+                               href="http://activemq.apache.org/"
+                               title="The most popular and powerful open source Message Broker">ActiveMQ</a> 
+                            <a style="float:right; width:210px;display:block;text-indent:-5000px;text-decoration:none;line-height:60px; margin-top:15px; margin-right:10px;"
+                               href="http://www.apache.org/" title="The Apache Software Foundation">ASF</a> 
+                        </div> 
+                    </div> 
+ 
+ 
+                    <div class="top_red_bar"> 
+                        <div id="site-breadcrumbs"> 
+                            <a href="index.html" title="Home">Home</a>
+                        </div> 
+                        <div id="site-quicklinks"><P> 
+                            <a href="http://activemq.apache.org/support.html"
+                               title="Get help and support using Apache ActiveMQ">Support</a></p> 
+                        </div> 
+                    </div> 
+ 
+                    <table border="0"> 
+                        <tbody> 
+                            <tr> 
+                                <td valign="top" width="100%" style="overflow:hidden;"> 
+                                    <div class="body-content">
 
 <h1>Chat Example</h1>
 
-Welcome to this little chat example
-<br>
-<br>
+<p>Welcome to the Ajax chat example</p>
 
 <div id="chatroom">
 	<div id="chat"></div>
@@ -37,15 +116,104 @@ Welcome to this little chat example
 	<div id="members"></div>
 
 	<div id="input">
-		<div id="join" class="hidden">Username:&nbsp;<input id="username" type="text" />
-			<input id="joinB" class="button" type="submit" name="join" value="Join" />
+		<div id="join" class="hidden">
+			Username:&nbsp;
+			<input id="username" type="text"/>
+			<button id="joinB">Join</button>
+		</div>
+		<div id="joined" class="hidden">
+			Chat:&nbsp;
+			<input id="phrase" type="text" />
+			<button id="sendB">Send</button>
+			<button id="leaveB">Leave</button>
 		</div>
-	        <div id="joined" class="hidden">Chat:&nbsp;<input id="phrase" type="text"></input> 
-	        		<input id="sendB" class="button" type="submit" name="join" value="Send" />
-	        		<input id="leaveB" class="button" type="submit" name="join" value="Leave" />
-	        	</div>
 	</div>
 </div>
 
-</body>
-</html>
+<p>
+	This Chat example creates an ActiveMQ broker using the configuration
+	information found in the <code>web.xml</code> file. There isn't much there.
+	Just a name-value parameter named <code>org.apache.activemq.brokerURL</code>
+	is assigned a value of <code>vm://localhost?broker.persistent=false</code>.
+	This is enough however to lazy-initialize the broker when it is needed.
+</p>
+<p>
+	The client leverages a javascript library <code>amq.js</code> to perform all
+	of the JMS-related client side code. This involves establishing a
+	communication pipeline to the JMS server. This pipeline uses a long-poll
+	connection to the server. All JMS communication will be received down this
+	pipe, and when the JMS server has no traffic to send, this pipeline will
+	patiently wait until there is new traffic or until it times out. If a
+	timeout does occur, the connection will reconnect to the server for another
+	round. (Of course you will want/need to use a server that supports
+	continuations in order for this to scale beyond a few hundred clients.)
+</p>
+<p>
+	The <code>chat.js</code> file contains the script to respond to the UI
+	interactions. It also talks to the <code>amq.js</code> file to send messages
+	and provides a message handler that will respond to incoming JMS messages.
+</p>
+<p>
+	There is no server-side state in this application. The client sets up a JMS
+	Topic on the server and attaches itself as a listener to this topic. From
+	that point, all messages that are sent to the topic are received by each
+	listener. Even the list of members in the chat room are the result of
+	clients replying to a ping request.
+</p>
+<p>
+	Please note that <code>amq.js</code> has been refactored to allow AJAX calls
+	to be made using any javascript library. Example adapter classes for <a href="http://jquery.com/">jQuery</a>
+	and <a href="http://www.prototypejs.org/">Prototype</a> have been provided.
+</p>
+
+
+                                  </div> 
+                                </td> 
+                                <td valign="top"> 
+ 
+                                    <div class="navigation"> 
+                                        <div class="navigation_top"> 
+                                            <div class="navigation_bottom"> 
+                                                <H3>Useful Links</H3> 
+ 
+                                                <ul class="alternate" type="square"> 
+                                                    <li><a href="http://activemq.apache.org/"
+                                                           title="The most popular and powerful open source Message Broker">Documentation</a></li> 
+                                                    <li><a href="http://activemq.apache.org/faq.html">FAQ</a></li> 
+                                                    <li><a href="http://activemq.apache.org/download.html">Downloads</a> 
+                                                    </li> 
+                                                    <li><a href="http://activemq.apache.org/discussion-forums.html">Forums</a> 
+                                                    </li> 
+                                                </ul> 
+                                            </div> 
+                                        </div> 
+                                    </div> 
+                                </td> 
+                            </tr> 
+                        </tbody> 
+                    </table> 
+ 
+ 
+                    <div class="bottom_red_bar"></div> 
+                </div> 
+            </div> 
+        </div> 
+    </div> 
+    <div class="black_box"> 
+        <div class="footer"> 
+            <div class="footer_l"> 
+                <div class="footer_r"> 
+                    <div> 
+                        Copyright 2005-2007 The Apache Software Foundation.
+ 
+                        (<a href="?printable=true">printable version</a>)
+                    </div> 
+                </div> 
+            </div> 
+        </div> 
+    </div> 
+</div> 
+<div class="design_attribution"><a href="http://hiramchirino.com/">Graphic Design By Hiram</a></div> 
+ 
+</body> 
+</html> 

Added: activemq/trunk/activemq-web-demo/src/main/webapp/js/amq.js
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-web-demo/src/main/webapp/js/amq.js?rev=935623&view=auto
==============================================================================
--- activemq/trunk/activemq-web-demo/src/main/webapp/js/amq.js (added)
+++ activemq/trunk/activemq-web-demo/src/main/webapp/js/amq.js Mon Apr 19 15:27:15 2010
@@ -0,0 +1,232 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// AMQ Ajax handler
+// This class provides the main API for using the Ajax features of AMQ. It
+// allows JMS messages to be sent and received from javascript when used
+// with the org.apache.activemq.web.MessageListenerServlet.
+//
+// This version of the file provides an adapter interface for the jquery library
+// and a namespace for the Javascript file, private/public variables and
+// methods, and other scripting niceties. -- jim cook 2007/08/28
+
+var org = org || {};
+org.activemq = org.activemq || {};
+
+org.activemq.Amq = function() {
+	var connectStatusHandler;
+
+	// Just a shortcut to eliminate some redundant typing.
+	var adapter = org.activemq.AmqAdapter;
+
+	if (typeof adapter == 'undefined') {
+		throw 'An org.activemq.AmqAdapter must be declared before the amq.js script file.'
+	}
+
+	// The URI of the AjaxServlet.
+	var uri;
+
+	// The number of seconds that the long-polling socket will stay connected.
+	// Best to keep this to a value less than one minute.
+	var timeout;
+
+	// Poll delay. if set to positive integer, this is the time to wait in ms
+	// before sending the next poll after the last completes.
+	var pollDelay;
+
+	// Inidicates whether logging is active or not. Not by default.
+	var logging = false;
+
+	// 5 second delay if an error occurs during poll. This could be due to
+	// server capacity problems or a timeout condition.
+	var pollErrorDelay = 5000;
+
+	// Map of handlers that will respond to message receipts. The id used during
+	// addListener(id, destination, handler) is used to key the callback
+	// handler.  
+	var messageHandlers = {};
+
+	// Indicates whether an AJAX post call is in progress.
+	var batchInProgress = false;
+
+	// A collection of pending messages that accumulate when an AJAX call is in
+	// progress. These messages will be delivered as soon as the current call
+	// completes. The array contains objects in the format { destination,
+	// message, messageType }.
+	var messageQueue = [];
+
+	/**
+	 * Iterate over the returned XML and for each message in the response, 
+	 * invoke the handler with the matching id.
+	 */
+	var messageHandler = function(data) {
+		var response = data.getElementsByTagName("ajax-response");
+		if (response != null && response.length == 1) {
+			connectStatusHandler(true);
+			var responses = response[0].childNodes;    // <response>
+			for (var i = 0; i < responses.length; i++) {
+				var responseElement = responses[i];
+
+				// only process nodes of type element.....
+				if (responseElement.nodeType != 1) continue;
+
+				var id = responseElement.getAttribute('id');
+
+				var handler = messageHandlers[id];
+
+				if (logging && handler == null) {
+					adapter.log('No handler found to match message with id = ' + id);
+					continue;
+				}
+
+				// Loop thru and handle each <message>
+				for (var j = 0; j < responseElement.childNodes.length; j++) {
+					handler(responseElement.childNodes[j]);
+				}
+			}
+		}
+	};
+
+	var errorHandler = function(xhr, status, ex) {
+		connectStatusHandler(false);
+		if (logging) adapter.log('Error occurred in ajax call. HTTP result: ' +
+		                         xhr.status + ', status: ' + status);
+	}
+
+	var pollErrorHandler = function(xhr, status, ex) {
+		connectStatusHandler(false);
+		if (status === 'error' && xhr.status === 0) {
+			if (logging) adapter.log('Server connection dropped.');
+			setTimeout(function() { sendPoll(); }, pollErrorDelay);
+			return;
+		}
+		if (logging) adapter.log('Error occurred in poll. HTTP result: ' +
+		                         xhr.status + ', status: ' + status);
+		setTimeout(function() { sendPoll(); }, pollErrorDelay);
+	}
+
+	var pollHandler = function(data) {
+		try {
+			messageHandler(data);
+		} catch(e) {
+			if (logging) adapter.log('Exception in the poll handler: ' + data, e);
+			throw(e);
+		} finally {
+			setTimeout(sendPoll, pollDelay);
+		}
+	};
+
+	var sendPoll = function() {
+		// Workaround IE6 bug where it caches the response
+		// Generate a unique query string with date and random
+		var now = new Date();
+		var data = 'timeout=' + timeout * 1000
+				 + '&d=' + now.getTime()
+				 + '&r=' + Math.random();
+				 
+		var options = { method: 'get',
+			data: data,
+			success: pollHandler,
+			error: pollErrorHandler};
+		adapter.ajax(uri, options);
+	};
+
+	var sendJmsMessage = function(destination, message, type) {
+		// Add message to outbound queue
+		if (batchInProgress) {
+			messageQueue[messageQueue.length] = {
+				destination: destination,
+				message: message,
+				messageType: type
+			};
+		} else {
+			org.activemq.Amq.startBatch();
+			adapter.ajax(uri, { method: 'post',
+				data: 'destination=' + destination + '&message=' + message + '&type=' + type,
+				error: errorHandler,
+				success: org.activemq.Amq.endBatch});
+		}
+	};
+
+	var buildParams = function(msgs) {
+		var s = [];
+		for (var i = 0, c = msgs.length; i < c; i++) {
+			if (i != 0) s[s.length] = '&';
+			s[s.length] = ((i == 0) ? 'destination' : 'd' + i);
+			s[s.length] = '=';
+			s[s.length] = msgs[i].destination;
+			s[s.length] = ((i == 0) ? '&message' : '&m' + i);
+			s[s.length] = '=';
+			s[s.length] = msgs[i].message;
+			s[s.length] = ((i == 0) ? '&type' : '&t' + i);
+			s[s.length] = '=';
+			s[s.length] = msgs[i].messageType;
+		}
+		return s.join('');
+	}
+
+	return {
+		init : function(options) {
+			connectStatusHandler = options.connectStatusHandler || function(connected){};
+			uri = options.uri || '/amq';
+			pollDelay = typeof options.pollDelay == 'number' ? options.pollDelay : 0;
+			timeout = typeof options.timeout == 'number' ? options.timeout : 25;
+			logging = options.logging;
+			adapter.init(options);
+			sendPoll();
+		},
+
+		startBatch : function() {
+			batchInProgress = true;
+		},
+
+		endBatch : function() {
+			if (messageQueue.length > 0) {
+				var body = buildParams(messageQueue);
+				messageQueue.length = 0;
+				org.activemq.Amq.startBatch();
+				adapter.ajax(uri, {
+					method: 'post',
+					data: body,
+					success: org.activemq.Amq.endBatch, 
+					error: errorHandler});
+			} else {
+				batchInProgress = false;
+			}
+		},
+
+		// Send a JMS message to a destination (eg topic://MY.TOPIC).  Message
+		// should be xml or encoded xml content.
+		sendMessage : function(destination, message) {
+			sendJmsMessage(destination, message, 'send');
+		},
+
+		// Listen on a channel or topic.
+		// handler must be a function taking a message argument
+		addListener : function(id, destination, handler) {
+			messageHandlers[id] = handler;
+			sendJmsMessage(destination, id, 'listen');
+		},
+
+		// remove Listener from channel or topic.
+		removeListener : function(id, destination) {
+			messageHandlers[id] = null;
+			sendJmsMessage(destination, id, 'unlisten');
+		}
+	};
+}();

Added: activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_dojo_adapter.js
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_dojo_adapter.js?rev=935623&view=auto
==============================================================================
--- activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_dojo_adapter.js (added)
+++ activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_dojo_adapter.js Mon Apr 19 15:27:15 2010
@@ -0,0 +1,80 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// AMQ Ajax Adapter for Dojo 
+// This class provides an adapter interface for the Dojo library to perform
+// some of the library-dependent tasks...namely logging and ajax.
+
+var org = org || {};
+org.activemq = org.activemq || {};
+
+org.activemq.AmqAdapter = {
+
+	init: function(options) {
+	},
+
+/**
+ *  Implement this method to make an AJAX call to the AjaxServlet. An
+ *  options object will accompany this class and will contain the properties
+ *  that describe the details of the AJAX call. The options object will
+ *  have the following properties:
+ *
+ *  - method:  'get' or 'post'
+ *  - data:    query data to accompany the post or get.
+ *  - success: A callback function that is invoked upon successful
+ *             completion of the AJAX call. The parameter is:
+ *             - data: The result of the AJAX call. In the case of XML
+ *                     data should resolve to a Document element.
+ *  - error:   A callback when some type of error occurs. The callback
+ *             function's parameters should be:
+ *             - xhr:    The XmlHttpRequest object.
+ *             - status: A text string of the status.
+ *             - ex:     The exception that caused the error.
+ */
+	ajax: function(uri, options) {
+		if (options.method == 'post') {
+			dojo.xhrPost({
+				url: uri,
+				handleAs: "xml",
+				postData: options.data,
+				load : options.success ? options.success : function() {},
+				error: options.error ? function(ex, ioargs) {
+						options.error(ioargs.xhr,ioargs.xhr.status, ex);
+					} : function() {}				
+			});
+		} else {
+			if (options.data)
+			{
+				uri += "?";
+				uri += options.data;
+			}
+			dojo.xhrGet({
+                                url: uri,
+				handleAs: "xml",
+				load : options.success ? options.success : function() {},
+				error: options.error ? function(ex, ioargs) {
+						options.error(ioargs.xhr,ioargs.xhr.status, ex);
+					} : function() {}
+			});
+		}
+	},
+
+	log: function(message, exception) {
+		if (typeof console != 'undefined' && console.log) console.log(message);
+	}
+};

Added: activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_jquery_adapter.js
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_jquery_adapter.js?rev=935623&view=auto
==============================================================================
--- activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_jquery_adapter.js (added)
+++ activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_jquery_adapter.js Mon Apr 19 15:27:15 2010
@@ -0,0 +1,80 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// AMQ Ajax Adapter for jQuery
+// This class provides an adapter interface for the jquery library to perform
+// some of the library-dependent tasks...namely logging and ajax.
+
+var org = org || {};
+org.activemq = org.activemq || {};
+
+org.activemq.AmqAdapter = {
+
+	init: function(options) {
+	},
+
+	/**
+	 *  Implement this method to make an AJAX call to the AjaxServlet. An
+	 *  options object will accompany this class and will contain the properties
+	 *  that describe the details of the AJAX call. The options object will
+	 *  have the following properties:
+	 *
+	 *  - method:  'get' or 'post'
+	 *  - data:    query data to accompany the post or get.
+	 *  - success: A callback function that is invoked upon successful
+	 *             completion of the AJAX call. The parameter is:
+	 *             - data: The result of the AJAX call. In the case of XML
+	 *                     data should resolve to a Document element.
+	 *  - error:   A callback when some type of error occurs. The callback
+	 *             function's parameters should be:
+	 *             - xhr:    The XmlHttpRequest object.
+	 *             - status: A text string of the status.
+	 *             - ex:     The exception that caused the error.
+	 */
+	ajax: function(uri, options) {
+		if (options.method == 'post') {
+			jQuery.ajax({
+				type: "POST",
+				url: uri,
+				data: options.data,
+				success: options.success || function(){},
+				error: options.error || function(){},
+				beforeSend: function(xhr) {
+					/* Force "Connection: close" for Mozilla browsers to work around
+					 * a bug where XMLHttpReqeuest sends an incorrect Content-length
+					 * header. See Mozilla Bugzilla #246651.
+					 */
+					xhr.setRequestHeader("Connection", 'close');
+				}
+			});
+		} else {        
+			jQuery.ajax({
+				type: "GET",
+				url: uri,
+				data: options.data,
+				success: options.success || function(){},
+				error: options.error || function(){},
+				dataType: 'xml'
+				});
+		}
+	},
+
+	log: function(message, exception) {
+		if (typeof console != 'undefined' && console.log) console.log(message);
+	}
+};

Propchange: activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_jquery_adapter.js
------------------------------------------------------------------------------
    svn:executable = *

Added: activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_prototype_adapter.js
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_prototype_adapter.js?rev=935623&view=auto
==============================================================================
--- activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_prototype_adapter.js (added)
+++ activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_prototype_adapter.js Mon Apr 19 15:27:15 2010
@@ -0,0 +1,90 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+// AMQ Ajax Adapter for Prototype
+// This class provides an adapter interface for the prototype library to perform
+// some of the library-dependent tasks...namely logging and ajax.
+
+var org = org || {};
+org.activemq = org.activemq || {};
+
+org.activemq.AmqAdapter = {
+
+	init: function(options) {
+	},
+
+/**
+ *  Implement this method to make an AJAX call to the AjaxServlet. An
+ *  options object will accompany this class and will contain the properties
+ *  that describe the details of the AJAX call. The options object will
+ *  have the following properties:
+ *
+ *  - method:  'get' or 'post'
+ *  - data:    query data to accompany the post or get.
+ *  - success: A callback function that is invoked upon successful
+ *             completion of the AJAX call. The parameter is:
+ *             - data: The result of the AJAX call. In the case of XML
+ *                     data should resolve to a Document element.
+ *  - error:   A callback when some type of error occurs. The callback
+ *             function's parameters should be:
+ *             - xhr:    The XmlHttpRequest object.
+ *             - status: A text string of the status.
+ *             - ex:     The exception that caused the error.
+ */
+	ajax: function(uri, options) {
+		if (options.method == 'post') {
+			new Ajax.Request(uri, {
+				method: "post",
+				postBody: options.data,
+				onSuccess: options.success ? function(xhr, header) {
+					if (options.success) {
+						var ct = xhr.getResponseHeader("content-type");
+						var xml = ct && ct.indexOf("xml") >= 0;
+						var data = xml ? xhr.responseXML : xhr.responseText;
+						options.success(data);
+					}
+				} : function() {},
+				onFailure: options.error || function() {
+				},
+				onException: options.error || function() {
+				}
+			});
+		} else {
+			new Ajax.Request(uri, {
+				method: "get",
+				parameters: options.data,
+				onSuccess: function(xhr, header) {
+					if (options.success) {
+						var ct = xhr.getResponseHeader("content-type");
+						var xml = ct && ct.indexOf("xml") >= 0;
+						var data = xml ? xhr.responseXML : xhr.responseText;
+						options.success(data);
+					}
+				},
+				onFailure: options.error || function() {
+				},
+				onException: options.error || function() {
+				}
+			});
+		}
+	},
+
+	log: function(message, exception) {
+		if (typeof console != 'undefined' && console.log) console.log(message);
+	}
+};

Propchange: activemq/trunk/activemq-web-demo/src/main/webapp/js/amq_prototype_adapter.js
------------------------------------------------------------------------------
    svn:executable = *

Added: activemq/trunk/activemq-web-demo/src/main/webapp/js/chat.js
URL: http://svn.apache.org/viewvc/activemq/trunk/activemq-web-demo/src/main/webapp/js/chat.js?rev=935623&view=auto
==============================================================================
--- activemq/trunk/activemq-web-demo/src/main/webapp/js/chat.js (added)
+++ activemq/trunk/activemq-web-demo/src/main/webapp/js/chat.js Mon Apr 19 15:27:15 2010
@@ -0,0 +1,213 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+var amq = org.activemq.Amq;
+
+org.activemq.Chat = function() {
+	var last = '';
+
+	var user = null;
+
+	var chatTopic = 'topic://CHAT.DEMO';
+
+	var chat, join, joined, phrase, members, username = null;
+
+	var chatHandler = function(message) {
+		var type = message.getAttribute('type');
+		var from = message.getAttribute('from');
+
+		switch (type) {
+			// Incoming chat message
+			case 'chat' : {
+				var text = message.childNodes[0].data;
+
+				if (from == last) from = '...';
+				else {
+					last = from;
+					from += ':';
+				}
+
+				chat.innerHTML += '<span class=\'from\'>' + from + '&nbsp;</span><span class=\'text\'>' + text + '</span><br/>';
+				break;
+			}
+
+			// Incoming ping request, add the person's name to your list.
+			case 'ping' : {
+				members.innerHTML += '<span class="member">' + from + '</span><br/>';
+				break;
+			}
+
+			// someone new joined the chatroom, clear your list and
+			// broadcast your name to all users.
+			case 'join' : {
+				members.innerHTML = '';
+				if (user != null)
+					amq.sendMessage(chatTopic, '<message type="ping" from="' + user + '"/>');
+				chat.innerHTML += '<span class="alert"><span class="from">' + from + '&nbsp;</span><span class="text">has joined the room!</span></span><br/>';
+				break;
+			}
+
+			// Screw you guys, I'm going home...
+			// When I (and everyone else) receive a leave message, we broadcast
+			// our own names in a ping in order to update everyone's list.
+			// todo: Make this more efficient by simply removing the person's name from the list.
+			case 'leave': {
+				members.innerHTML = '';
+				chat.innerHTML += '<span class="alert"><span class="from">' + from + '&nbsp;</span><span class="text">has left the room!</span></span><br/>';
+
+				// If we are the one that is leaving...
+				if (from == user) {
+				// switch the input form
+					join.className = '';
+					joined.className = 'hidden';
+					username.focus();
+
+					user = null;
+					amq.removeListener('chat', chatTopic);
+				}
+				if (user != null)
+					amq.sendMessage(chatTopic, '<message type="ping" from="' + user + '"/>');
+				break;
+			}
+		}
+
+		chat.scrollTop = chat.scrollHeight - chat.clientHeight;
+	};
+
+	var getKeyCode = function (ev) {
+		var keyc;
+		if (window.event) keyc = window.event.keyCode;
+		else keyc = ev.keyCode;
+		return keyc;
+	};
+
+	// Again, you would generally use your particular js library to attach
+	// event handlers. However, I wanted to remove the dependency on the
+	// behaviors.js file in the original code, and I am demonstrating a library
+	// that can work with a variety of js libraries, so we are going old-school.
+	var addEvent = function(obj, type, fn) {
+		if (obj.addEventListener)
+			obj.addEventListener(type, fn, false);
+		else if (obj.attachEvent) {
+			obj["e"+type+fn] = fn;
+			obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
+			obj.attachEvent( "on"+type, obj[type+fn] );
+		}
+	};
+
+	var initEventHandlers = function() {
+		addEvent(username, 'keyup', function(ev) {
+			var keyc = getKeyCode(ev);
+			if (keyc == 13 || keyc == 10) {
+				org.activemq.Chat.join();
+				return false;
+			}
+			return true;
+		});
+
+		addEvent(document.getElementById('joinB'), 'click', function() {
+			org.activemq.Chat.join();
+			return true;
+		});
+
+		addEvent(phrase, 'keyup', function(ev) {
+			var keyc = getKeyCode(ev);
+
+			if (keyc == 13 || keyc == 10) {
+				var text = phrase.value;
+				phrase.value = '';
+				org.activemq.Chat.chat(text);
+				return false;
+			}
+			return true;
+		});
+
+		addEvent(document.getElementById('sendB'), 'click', function() {
+			var text = phrase.value;
+			phrase.value = '';
+			org.activemq.Chat.chat(text);
+		});
+
+		addEvent(document.getElementById('leaveB'), 'click', function() {
+			org.activemq.Chat.leave();
+			return false;
+		});
+	};
+
+	return {
+		join: function() {
+			var name = username.value;
+			if (name == null || name.length == 0) {
+				alert('Please enter a username!');
+			} else {
+				user = name;
+
+				amq.addListener('chat', chatTopic, chatHandler);
+				join.className = 'hidden';
+				joined.className = '';
+				phrase.focus();
+
+				amq.sendMessage(chatTopic, '<message type="join" from="' + user + '"/>');
+			}
+		},
+
+		leave: function() {
+			amq.sendMessage(chatTopic, '<message type="leave" from="' + user + '"/>');
+		},
+
+		chat: function(text) {
+			if (text != null && text.length > 0) {
+				// TODO more encoding?
+				text = text.replace('<', '&lt;');
+				text = text.replace('>', '&gt;');
+
+				amq.sendMessage(chatTopic, '<message type="chat" from="' + user + '">' + text + '</message>');
+			}
+		},
+
+		init: function() {
+			join = document.getElementById('join');
+			joined = document.getElementById('joined');
+			chat = document.getElementById('chat');
+			members = document.getElementById('members');
+			username = document.getElementById('username');
+			phrase = document.getElementById('phrase');
+
+			if (join.className == 'hidden' && joined.className == 'hidden') {
+				join.className = '';
+				joined.className = 'hidden';
+				username.focus();
+			}
+
+			initEventHandlers();
+		}
+	}
+}();
+
+
+
+
+
+
+
+
+
+
+
+
+

Propchange: activemq/trunk/activemq-web-demo/src/main/webapp/js/chat.js
------------------------------------------------------------------------------
    svn:executable = *