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: <input id="username" type="text" />
- <input id="joinB" class="button" type="submit" name="join" value="Join" />
+ <div id="join" class="hidden">
+ Username:
+ <input id="username" type="text"/>
+ <button id="joinB">Join</button>
+ </div>
+ <div id="joined" class="hidden">
+ Chat:
+ <input id="phrase" type="text" />
+ <button id="sendB">Send</button>
+ <button id="leaveB">Leave</button>
</div>
- <div id="joined" class="hidden">Chat: <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 + ' </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 + ' </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 + ' </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('<', '<');
+ text = text.replace('>', '>');
+
+ 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 = *