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 = *


Reply via email to