]> source.dussan.org Git - vaadin-framework.git/commitdiff
Upgrade to Atmosphere 1.0.13 (#11861)
authorJohannes Dahlström <johannesd@vaadin.com>
Tue, 21 May 2013 07:18:22 +0000 (10:18 +0300)
committerVaadin Code Review <review@vaadin.com>
Tue, 21 May 2013 11:45:16 +0000 (11:45 +0000)
Change-Id: Ie9281ff5e9805be89942bf3ca8259740f49e15ab

.classpath
WebContent/VAADIN/jquery.atmosphere.js
push/build.xml
push/ivy.xml
push/src/org/atmosphere/cpr/AtmosphereFramework.java [deleted file]
server/src/com/vaadin/server/Constants.java
shared/src/com/vaadin/shared/communication/PushConstants.java

index 381f0d280d057ba50206f859f791c46389fba83c..c6230a2c55ed545d1e4cace4962d7ec88335fa8f 100644 (file)
@@ -11,7 +11,6 @@
        <classpathentry kind="src" path="uitest/src"/>
        <classpathentry kind="src" path="buildhelpers/src"/>
        <classpathentry kind="src" path="shared/src"/>
-       <classpathentry kind="src" path="push/src"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
                <attributes>
                        <attribute name="owner.project.facets" value="java"/>
index e9def6ae9565b5a445e2d5790725be1890e233f6..2b176668c19586dd4acf2937a6b67a5c1240f3d1 100644 (file)
@@ -49,7 +49,7 @@ jQuery.atmosphere = function() {
     };
 
     return {
-        version : "1.0.12",
+        version : "1.0.13",
         requests : [],
         callbacks : [],
 
@@ -138,13 +138,16 @@ jQuery.atmosphere = function() {
              */
             var _response = {
                 status: 200,
+                reasonPhrase : "OK",
                 responseBody : '',
+                messages : [],
                 headers : [],
                 state : "messageReceived",
                 transport : "polling",
                 error: null,
                 request : null,
                 partialMessage : "",
+                errorHandled: false,
                 id : 0
             };
 
@@ -682,19 +685,21 @@ jQuery.atmosphere = function() {
                     _close();
                 };
 
-                _response.request = request;
-                var prevState = _response.state;
-                _response.state = state;
-                _response.status = 200;
-                var prevTransport = _response.transport;
-                _response.transport = transport;
+                if (_response.error == null) {
+                    _response.request = request;
+                    var prevState = _response.state;
+                    _response.state = state;
+                    _response.status = 200;
+                    var prevTransport = _response.transport;
+                    _response.transport = transport;
 
-                var _body = _response.responseBody;
-                _invokeCallback();
-                _response.responseBody = _body;
+                    var _body = _response.responseBody;
+                    _invokeCallback();
+                    _response.responseBody = _body;
 
-                _response.state = prevState;
-                _response.transport = prevTransport;
+                    _response.state = prevState;
+                    _response.transport = prevTransport;
+                }
             }
 
             /**
@@ -729,41 +734,43 @@ jQuery.atmosphere = function() {
                     type : rq.method,
                     dataType: "jsonp",
                     error : function(jqXHR, textStatus, errorThrown) {
-                        if (jqXHR.status < 300) {
+                        _response.error = true;
+                        if (jqXHR.status < 300 && rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) {
                             _reconnect(_jqxhr, rq);
                         } else {
-                            _prepareCallback(textStatus, "error", jqXHR.status, rq.transport);
+                            _onError(jqXHR.status, errorThrown);
                         }
                     },
                     jsonp : "jsonpTransport",
                     success: function(json) {
+                        if (rq.reconnect) {
+                            if (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest) {
+                                _readHeaders(_jqxhr, rq);
 
-                        if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
-                            _readHeaders(_jqxhr, rq);
-
-                            if (!rq.executeCallbackBeforeReconnect) {
-                                _reconnect(_jqxhr, rq);
-                            }
+                                if (!rq.executeCallbackBeforeReconnect) {
+                                    _reconnect(_jqxhr, rq);
+                                }
 
-                            var msg = json.message;
-                            if (msg != null && typeof msg != 'string') {
-                                try {
-                                    msg = jQuery.stringifyJSON(msg);
-                                } catch (err) {
-                                    // The message was partial
+                                var msg = json.message;
+                                if (msg != null && typeof msg != 'string') {
+                                    try {
+                                        msg = jQuery.stringifyJSON(msg);
+                                    } catch (err) {
+                                        // The message was partial
+                                    }
                                 }
-                            }
 
-                            if (_handleProtocol(rq, msg)) {
-                                _prepareCallback(msg, "messageReceived", 200, rq.transport);
-                            }
+                                if (_handleProtocol(rq, msg)) {
+                                    _prepareCallback(msg, "messageReceived", 200, rq.transport);
+                                }
 
-                            if (rq.executeCallbackBeforeReconnect) {
-                                _reconnect(_jqxhr, rq);
+                                if (rq.executeCallbackBeforeReconnect) {
+                                    _reconnect(_jqxhr, rq);
+                                }
+                            } else {
+                                jQuery.atmosphere.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]);
+                                _onError(0, "maxRequest reached");
                             }
-                        } else {
-                            jQuery.atmosphere.log(_request.logLevel, ["JSONP reconnect maximum try reached " + _request.requestCount]);
-                            _onError();
                         }
                     },
                     data : rq.data,
@@ -802,29 +809,32 @@ jQuery.atmosphere = function() {
                     url : url,
                     type : rq.method,
                     error : function(jqXHR, textStatus, errorThrown) {
+                        _response.error = true;
                         if (jqXHR.status < 300) {
                             _reconnect(_jqxhr, rq);
                         } else {
-                            _prepareCallback(textStatus, "error", jqXHR.status, rq.transport);
+                            _onError(jqXHR.status, errorThrown);
                         }
                     },
                     success: function(data, textStatus, jqXHR) {
 
-                        if (rq.reconnect && (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
-                            if (!rq.executeCallbackBeforeReconnect) {
-                                _reconnect(_jqxhr, rq);
-                            }
+                        if (rq.reconnect) {
+                            if (rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest) {
+                                if (!rq.executeCallbackBeforeReconnect) {
+                                    _reconnect(_jqxhr, rq);
+                                }
 
-                            if (_handleProtocol(rq, data)) {
-                                _prepareCallback(data, "messageReceived", 200, rq.transport);
-                            }
+                                if (_handleProtocol(rq, data)) {
+                                    _prepareCallback(data, "messageReceived", 200, rq.transport);
+                                }
 
-                            if (rq.executeCallbackBeforeReconnect) {
-                                _reconnect(_jqxhr, rq);
+                                if (rq.executeCallbackBeforeReconnect) {
+                                    _reconnect(_jqxhr, rq);
+                                }
+                            } else {
+                                jQuery.atmosphere.log(_request.logLevel, ["AJAX reconnect maximum try reached " + _request.requestCount]);
+                                _onError(0, "maxRequest reached");
                             }
-                        } else {
-                            jQuery.atmosphere.log(_request.logLevel, ["AJAX reconnect maximum try reached " + _request.requestCount]);
-                            _onError();
                         }
                     },
                     beforeSend : function(jqXHR) {
@@ -912,7 +922,14 @@ jQuery.atmosphere = function() {
                     }
                     return;
                 }
-                _sse = new EventSource(location, {withCredentials: _request.withCredentials});
+
+                try {
+                     _sse = new EventSource(location, {withCredentials: _request.withCredentials});
+                } catch (e) {
+                    _onError(0, e);
+                    _reconnectWithFallbackTransport("SSE failed. Downgrading to fallback transport and resending");
+                    return;
+                }
 
                 if (_request.connectTimeout > 0) {
                     _request.id = setTimeout(function() {
@@ -944,31 +961,25 @@ jQuery.atmosphere = function() {
                         return;
                     }
 
-                    if (!_handleProtocol(_request, message.data)) return;
+                    var data = message.data;
+
+                    if (!_handleProtocol(_request, data)) return;
 
                     _response.state = 'messageReceived';
                     _response.status = 200;
 
-                    var message = message.data;
-                    var skipCallbackInvocation = _trackMessageSize(message, _request, _response);
-
-                    if (jQuery.trim(message).length == 0) {
-                        skipCallbackInvocation = true;
-                    }
-
+                    var skipCallbackInvocation = _trackMessageSize(data, _request, _response);
                     if (!skipCallbackInvocation) {
                         _invokeCallback();
                         _response.responseBody = '';
+                        _response.messages = [];
                     }
                 };
 
                 _sse.onerror = function(message) {
 
                     clearTimeout(_request.id);
-                    _response.state = 'closed';
-                    _response.responseBody = "";
-                    _response.status = !sseOpened ? 501 : 200;
-                    _invokeCallback();
+                    _invokeClose(sseOpened);
                     _clearState();
 
                     if (_abordingConnection) {
@@ -981,9 +992,10 @@ jQuery.atmosphere = function() {
                                 _executeSSE(true);
                             }, _request.reconnectInterval);
                             _response.responseBody = "";
+                            _response.messages = [];
                         } else {
                             jQuery.atmosphere.log(_request.logLevel, ["SSE reconnect maximum try reached " + _requestCount]);
-                            _onError();
+                            _onError(0, "maxReconnectOnClose reached");
                         }
                     }
                 };
@@ -1025,7 +1037,6 @@ jQuery.atmosphere = function() {
                 }
 
                 _websocket = _getWebSocket(location);
-
                 if (_request.connectTimeout > 0) {
                     _request.id = setTimeout(function() {
                         if (!webSocketOpened) {
@@ -1062,6 +1073,7 @@ jQuery.atmosphere = function() {
                     }
 
                     webSocketOpened = true;
+                    _websocket.webSocketOpened = webSocketOpened;
 
                     if (_request.method == 'POST') {
                         _response.state = "messageReceived";
@@ -1078,17 +1090,18 @@ jQuery.atmosphere = function() {
                         }, _request.reconnectInterval)
                     }, _request.timeout);
 
-                    if (!_handleProtocol(_request, message.data)) return;
+                    var data = message.data;
+
+                    if (!_handleProtocol(_request, data)) return;
 
                     _response.state = 'messageReceived';
                     _response.status = 200;
 
-                    var message = message.data;
-                    var skipCallbackInvocation = _trackMessageSize(message, _request, _response);
-
+                    var skipCallbackInvocation = _trackMessageSize(data, _request, _response);
                     if (!skipCallbackInvocation) {
                         _invokeCallback();
                         _response.responseBody = '';
+                        _response.messages = [];
                     }
                 };
 
@@ -1098,6 +1111,7 @@ jQuery.atmosphere = function() {
 
                 _websocket.onclose = function(message) {
                     if (closed) return
+                    clearTimeout(_request.id);
 
                     var reason = message.reason;
                     if (reason === "") {
@@ -1133,12 +1147,7 @@ jQuery.atmosphere = function() {
                     jQuery.atmosphere.warn("Websocket closed, reason: " + reason);
                     jQuery.atmosphere.warn("Websocket closed, wasClean: " + message.wasClean);
 
-                    _response.state = 'closed';
-                    _response.responseBody = "";
-                    _response.status = !webSocketOpened ? 501 : 200;
-                    _invokeCallback();
-                    clearTimeout(_request.id);
-
+                    _invokeClose(webSocketOpened);
                     closed = true;
 
                     if (_abordingConnection) {
@@ -1151,12 +1160,13 @@ jQuery.atmosphere = function() {
                         if (_request.reconnect && _requestCount++ < _request.maxReconnectOnClose) {
                             _request.id = setTimeout(function() {
                                 _response.responseBody = "";
+                                _response.messages = [];
                                 _executeWebSocket(true);
                             }, _request.reconnectInterval);
                         } else {
                             jQuery.atmosphere.log(_request.logLevel, ["Websocket reconnect maximum try reached " + _requestCount]);
                             jQuery.atmosphere.warn("Websocket error, reason: " + message.reason);
-                            _onError();
+                            _onError(0, "maxReconnectOnClose reached");
                         }
                     }
                 };
@@ -1164,22 +1174,25 @@ jQuery.atmosphere = function() {
 
             function _handleProtocol(request, message) {
                 // The first messages is always the uuid.
-                if (request.enableProtocol && request.firstMessage) {
+                if (jQuery.trim(message) != 0 && request.enableProtocol && request.firstMessage) {
                     request.firstMessage  = false;
                     var messages =  message.split(request.messageDelimiter);
-                    request.uuid = messages[0];
-                    request.stime = messages[1];
+                    var pos = messages.length == 2 ? 0 : 1;
+                    request.uuid = jQuery.trim(messages[pos]);
+                    request.stime = jQuery.trim(messages[pos + 1]);
                     return false;
                 }
                 return true;
             }
 
-            function _onError() {
+            function _onError(code, reason) {
                 _clearState();
 
                 _response.state = 'error';
+                _response.reasonPhrase = reason;
                 _response.responseBody = "";
-                _response.status = 500;
+                _response.messages = [];
+                _response.status = code;
                 _invokeCallback();
             }
 
@@ -1203,7 +1216,7 @@ jQuery.atmosphere = function() {
                     var messageLength = 0;
                     var messageStart = message.indexOf(request.messageDelimiter);
                     while (messageStart != -1) {
-                        messageLength = message.substring(messageLength, messageStart);
+                        messageLength = jQuery.trim(message.substring(messageLength, messageStart));
                         message = message.substring(messageStart + request.messageDelimiter.length, message.length);
 
                         if (message.length == 0 || message.length < messageLength) break;
@@ -1220,8 +1233,11 @@ jQuery.atmosphere = function() {
 
                     if (messages.length != 0) {
                         response.responseBody = messages.join(request.messageDelimiter);
+                        response.messages = messages;
                         return false;
                     } else {
+                        response.responseBody = "";
+                        response.messages = [];
                         return true;
                     }
                 } else {
@@ -1246,15 +1262,16 @@ jQuery.atmosphere = function() {
                 }
 
                 _request.transport = _request.fallbackTransport;
-                var reconnect = _request.reconnect && _requestCount++ < _request.maxReconnectOnClose;
-                if (reconnect && _request.transport != 'none' || _request.transport == null) {
+                var reconnectInterval = _request.connectTimeout == -1 ? 0 : _request.connectTimeout;
+                if (_request.reconnect && _request.transport != 'none' || _request.transport == null) {
                     _request.method = _request.fallbackMethod;
                     _response.transport = _request.fallbackTransport;
+                    _request.fallbackTransport = 'none';
                     _request.id = setTimeout(function() {
                         _execute();
-                    }, _request.reconnectInterval);
-                } else if (!reconnect) {
-                    _onError();
+                    }, reconnectInterval);
+                } else {
+                    _onError(500, "Unable to reconnect with fallback transport");
                 }
             }
 
@@ -1357,6 +1374,9 @@ jQuery.atmosphere = function() {
                     rq = request;
                 }
 
+                rq.lastIndex = 0;
+                rq.readyState = 0;
+
                 // CORS fake using JSONP
                 if ((rq.transport == 'jsonp') || ((rq.enableXDR) && (jQuery.atmosphere.checkCORSSupport()))) {
                     _jsonp(rq);
@@ -1380,6 +1400,14 @@ jQuery.atmosphere = function() {
                     }
                 }
 
+                var reconnectF =  function() {
+                    if (rq.reconnect && _requestCount++ < rq.maxReconnectOnClose) {
+                        _reconnect(ajaxRequest, rq, true);
+                    } else {
+                        _onError(0, "maxReconnectOnClose reached");
+                    }
+                };
+
                 if (rq.reconnect && ( rq.maxRequest == -1 || rq.requestCount++ < rq.maxRequest)) {
                     var ajaxRequest = _buildAjaxRequest();
                     _doRequest(ajaxRequest, rq, true);
@@ -1392,162 +1420,129 @@ jQuery.atmosphere = function() {
                         _response.transport = rq.transport;
                     }
 
-                    if (!jQuery.browser.msie) {
-                        ajaxRequest.onerror = function() {
-                            try {
-                                _response.status = XMLHttpRequest.status;
-                            } catch(e) {
-                                _response.status = 500;
-                            }
+                    ajaxRequest.onabort = function () {
+                        _invokeClose(true);
+                    };
 
-                            if (!_response.status) {
-                                _response.status = 500;
-                            }
-                            _clearState();
+                    ajaxRequest.onerror = function() {
+                        _response.error = true;
+                        try {
+                            _response.status = XMLHttpRequest.status;
+                        } catch(e) {
+                            _response.status = 500;
+                        }
 
-                            if (rq.reconnect) {
-                                _reconnect(ajaxRequest, rq, true);
-                            } else {
-                                _onError();
-                            }
-                        };
-                    }
+                        if (!_response.status) {
+                            _response.status = 500;
+                        }
+                        _clearState();
+                        if (!_response.errorHandled) {
+                            reconnectF();
+                        }
+                    };
 
                     ajaxRequest.onreadystatechange = function() {
                         if (_abordingConnection) {
                             return;
                         }
-
+                        _response.error = null;
                         var skipCallbackInvocation = false;
                         var update = false;
 
-                        // Remote server disconnected us, reconnect.
-                        if (rq.transport == 'streaming'
+
+                        // Opera doesn't call onerror if the server disconnect.
+                        if (jQuery.browser.opera
+                            && rq.transport == 'streaming'
                             && rq.readyState > 2
                             && ajaxRequest.readyState == 4) {
 
                             rq.readyState = 0;
                             rq.lastIndex = 0;
 
-                            _reconnect(ajaxRequest, rq, true);
+                            reconnectF();
                             return;
                         }
 
                         rq.readyState = ajaxRequest.readyState;
 
-                        if (ajaxRequest.readyState == 4) {
-                            if (jQuery.browser.msie) {
-                                update = true;
-                            } else if (rq.transport == 'streaming') {
-                                update = true;
-                            } else if (rq.transport == 'long-polling') {
-                                update = true;
-                                clearTimeout(rq.id);
-                            }
-                        } else if (rq.transport == 'streaming' && jQuery.browser.msie && ajaxRequest.readyState >= 3) {
+                        if (rq.transport == 'streaming' && ajaxRequest.readyState >= 3) {
                             update = true;
-                        } else if (!jQuery.browser.msie && ajaxRequest.readyState == 3 && ajaxRequest.status == 200 && rq.transport != 'long-polling') {
+                        } else if (rq.transport == 'long-polling' && ajaxRequest.readyState === 4) {
                             update = true;
-                        } else {
-                            clearTimeout(rq.id);
                         }
+                        clearTimeout(rq.id);
 
                         if (update) {
+                            // MSIE 9 and lower status can be higher than 1000, Chrome can be 0
+                            var status = 0;
+                            if (ajaxRequest.readyState != 0) {
+                                status = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status;
+                            }
+
+                            if (status >= 300 || status == 0) {
+                                // Prevent onerror callback to be called
+                                _response.errorHandled = true;
+                                _clearState();
+                                reconnectF();
+                                return;
+                            }
                             var responseText = ajaxRequest.responseText;
 
-                            // MSIE status can be higher than 1000, Chrome can be 0
-                            if (ajaxRequest.status >= 500 || ajaxRequest.status == 0) {
-                                if (rq.reconnect) {
-                                    _reconnect(ajaxRequest, rq, true);
-                                } else {
-                                    _onError();
+                            if (jQuery.trim(responseText.length) == 0 && rq.transport == 'long-polling') {
+                                // For browser that aren't support onabort
+                                if (!ajaxRequest.hasData) {
+                                    reconnectF();
+                                }  else {
+                                    ajaxRequest.hasData = false;
                                 }
                                 return;
                             }
+                            ajaxRequest.hasData = true;
 
                             _readHeaders(ajaxRequest, _request);
 
                             if (rq.transport == 'streaming') {
-                                var text = responseText.substring(rq.lastIndex, responseText.length);
-                                _response.isJunkEnded = true;
-
-                                //fix junk is comming in parts
-                                if (!_response.junkFull && (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1 || text.indexOf("<!-- EOD -->") == -1)) {
-                                    return;
-                                }
-                                _response.junkFull = true;
-
-                                //if it's the start and we see the junk start
-                                //fix for reconnecting on chrome - junk is comming in parts
-                                if (rq.lastIndex == 0 && text.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1 && text.indexOf("<!-- EOD -->") != -1) {
-                                    _response.isJunkEnded = false;
-                                }
-
-                                if (!_response.isJunkEnded) {
-                                    var endOfJunk = "<!-- EOD -->";
-                                    var endOfJunkLength = endOfJunk.length;
-                                    var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength;
-
-                                    if (junkEnd > endOfJunkLength && junkEnd != text.length) {
-                                        _response.responseBody = text.substring(junkEnd);
-                                        rq.lastIndex = responseText.length;
-                                        if (!_handleProtocol( _request, _response.responseBody)) {
-                                            return;
-                                        }
-                                        skipCallbackInvocation = _trackMessageSize(_response.responseBody, rq, _response);
-                                    } else {
-                                        skipCallbackInvocation = true;
-                                    }
-                                } else {
+                                if (!jQuery.browser.opera) {
                                     var message = responseText.substring(rq.lastIndex, responseText.length);
                                     rq.lastIndex = responseText.length;
-                                    if (!_handleProtocol( _request, message)) {
+                                    if (!_handleProtocol(_request, message)) {
                                         return;
                                     }
                                     skipCallbackInvocation = _trackMessageSize(message, rq, _response);
-                                }
-                                rq.lastIndex = responseText.length;
-
-                                if (jQuery.browser.opera) {
-                                    jQuery.atmosphere.iterate(function() {
-                                        if (ajaxRequest.responseText.length > rq.lastIndex) {
+                                } else {
+                                    jQuery.atmosphere.iterate(function () {
+                                        if (_response.status != 500 && ajaxRequest.responseText.length > rq.lastIndex) {
                                             try {
                                                 _response.status = ajaxRequest.status;
-                                                _response.headers = parseHeaders(ajaxRequest.getAllResponseHeaders());
-
-                                                _readHeaders(ajaxRequest, _request);
                                             }
-                                            catch(e) {
+                                            catch (e) {
                                                 _response.status = 404;
                                             }
                                             _response.state = "messageReceived";
-                                            _response.responseBody = ajaxRequest.responseText.substring(rq.lastIndex);
+
+                                            var message = ajaxRequest.responseText.substring(rq.lastIndex);
                                             rq.lastIndex = ajaxRequest.responseText.length;
+                                            if (_handleProtocol(_request, message)) {
+                                                skipCallbackInvocation = _trackMessageSize(message, rq, _response);
+                                                if (!skipCallbackInvocation) {
+                                                    _invokeCallback();
+                                                }
 
-                                            if (!_handleProtocol( _request, _response.responseBody)) {
-                                                _reconnect(ajaxRequest, rq, false);
-                                                return;
-                                            }
-                                            _invokeCallback();
-                                            if ((rq.transport == 'streaming') && (ajaxRequest.responseText.length > rq.maxStreamingLength)) {
-                                                // Close and reopen connection on large data received
-                                                _clearState();
-                                                _doRequest(_buildAjaxRequest(), rq, true);
+                                                _verifyStreamingLength(ajaxRequest, rq);
                                             }
+                                        } else if (_response.status > 400){
+                                            rq.lastIndex = ajaxRequest.responseText.length;
+                                            return false;
                                         }
                                     }, 0);
                                 }
-
-                                if (skipCallbackInvocation) {
-                                    return;
-                                }
                             } else {
                                 if (!_handleProtocol( _request, responseText)) {
                                     _reconnect(ajaxRequest, rq, false);
                                     return;
                                 }
 
-                                _trackMessageSize(responseText, rq, _response);
+                                skipCallbackInvocation = _trackMessageSize(responseText, rq, _response);
                                 rq.lastIndex = responseText.length;
                             }
 
@@ -1575,17 +1570,15 @@ jQuery.atmosphere = function() {
                                 jQuery.atmosphere.log(rq.logLevel, ["parent.callback no longer supported with 0.8 version and up. Please upgrade"]);
                             }
 
-                            _invokeCallback();
+                            if (!skipCallbackInvocation) {
+                                _invokeCallback();
+                            }
 
                             if (rq.executeCallbackBeforeReconnect) {
                                 _reconnect(ajaxRequest, rq, false);
                             }
 
-                            if ((rq.transport == 'streaming') && (responseText.length > rq.maxStreamingLength)) {
-                                // Close and reopen connection on large data received
-                                _clearState();
-                                _doRequest(_buildAjaxRequest(), rq, true);
-                            }
+                            _verifyStreamingLength(ajaxRequest, rq);
                         }
                     };
                     ajaxRequest.send(rq.data);
@@ -1606,7 +1599,7 @@ jQuery.atmosphere = function() {
                     if (rq.logLevel == 'debug') {
                         jQuery.atmosphere.log(rq.logLevel, ["Max re-connection reached."]);
                     }
-                    _onError();
+                    _onError(0, "maxRequest reached");
                 }
             }
 
@@ -1651,13 +1644,13 @@ jQuery.atmosphere = function() {
                     if (request.trackMessageLength) {
                         ajaxRequest.setRequestHeader("X-Atmosphere-TrackMessageSize", "true")
                     }
-
-                    if (request.contentType != '') {
-                        ajaxRequest.setRequestHeader("Content-Type", request.contentType);
-                    }
                     ajaxRequest.setRequestHeader("X-Atmosphere-tracking-id", request.uuid);
                 }
 
+                if (request.contentType != '') {
+                    ajaxRequest.setRequestHeader("Content-Type", request.contentType);
+                }
+
                 jQuery.each(request.headers, function(name, value) {
                     var h = jQuery.isFunction(value) ? value.call(this, ajaxRequest, request, create, _response) : value;
                     if (h != null) {
@@ -1667,17 +1660,26 @@ jQuery.atmosphere = function() {
             }
 
             function _reconnect(ajaxRequest, request, force) {
-                var reconnect = request.reconnect && _requestCount++ < request.maxReconnectOnClose;
+                if (force || request.transport != 'streaming') {
+                    if ( request.reconnect || (request.suspend && _subscribed)) {
+                        var status = 0;
+                        if (ajaxRequest.readyState != 0) {
+                            status  = ajaxRequest.status > 1000 ? 0 : ajaxRequest.status;
+                        }
+                        _response.status = status == 0 ? 204 : status;
+                        _response.reason = status == 0 ? "Server resumed the connection or down." : "OK";
 
-                if (reconnect && force || (request.suspend && ajaxRequest.status == 200 && request.transport != 'streaming' && _subscribed)) {
-                    if (request.reconnect) {
-                        _open('re-opening', request.transport, request);
-                        request.id = setTimeout(function() {
-                            _executeRequest();
-                        }, request.reconnectInterval);
+                        var reconnectInterval = (request.connectTimeout == -1) ? 0 : request.connectTimeout;
+
+                        // Reconnect immedialtely
+                        if (!force) {
+                            request.id = setTimeout(function () {
+                                _executeRequest(request);
+                            }, reconnectInterval);
+                        } else {
+                            _executeRequest(request);
+                        }
                     }
-                } else if (!reconnect) {
-                    _onError();
                 }
             }
 
@@ -1702,21 +1704,6 @@ jQuery.atmosphere = function() {
                 var lastIndex = 0;
                 var xdrCallback = function (xdr) {
                     var responseBody = xdr.responseText;
-                    var isJunkEnded = false;
-
-                    if (responseBody.indexOf("<!-- Welcome to the Atmosphere Framework.") != -1) {
-                        isJunkEnded = true;
-                    }
-
-                    if (isJunkEnded) {
-                        var endOfJunk = "<!-- EOD -->";
-                        var endOfJunkLenght = endOfJunk.length;
-                        var junkEnd = responseBody.indexOf(endOfJunk);
-                        if (junkEnd !== -1) {
-                            responseBody = responseBody.substring(junkEnd + endOfJunkLenght + lastIndex);
-                            lastIndex += responseBody.length;
-                        }
-                    }
 
                     if (!_handleProtocol(request, responseBody)) return;
 
@@ -1747,10 +1734,8 @@ jQuery.atmosphere = function() {
                 xdr.onerror = function() {
                     // If the server doesn't send anything back to XDR will fail with polling
                     if (rq.transport != 'polling') {
-                        _prepareCallback(xdr.responseText, "error", 500, transport);
+                        _reconnect(xdr, rq, false);
                     }
-
-                    _reconnect(xdr, rq, false);
                 };
 
                 // Handles close event
@@ -1873,23 +1858,7 @@ jQuery.atmosphere = function() {
                                     clone.appendChild(cdoc.createTextNode("."));
 
                                     var text = clone.innerText;
-                                    var isJunkEnded = true;
-
-                                    if (text.indexOf("<!-- Welcome to the Atmosphere Framework.") == -1) {
-                                        isJunkEnded = false;
-                                    }
-
-                                    if (isJunkEnded) {
-                                        var endOfJunk = "<!-- EOD -->";
-                                        var endOfJunkLength = endOfJunk.length;
-                                        var junkEnd = text.indexOf(endOfJunk) + endOfJunkLength;
-
-                                        text = text.substring(junkEnd);
-                                    }
-
                                     text = text.substring(0, text.length - 1);
-
-                                    _handleProtocol(rq, text);
                                     return text;
 
                                 };
@@ -1918,11 +1887,14 @@ jQuery.atmosphere = function() {
                                     var text = readResponse();
                                     if (text.length > rq.lastIndex) {
                                         _response.status = 200;
+                                        _response.error = null;
 
-                                        // Empties response every time that it is handled
-                                        res.innerText = "";
-                                        _prepareCallback(text, "messageReceived", 200, rq.transport);
-
+                                        var message = text;
+                                        if (message.length != 0 && _handleProtocol(rq, message)) {
+                                            // Empties response every time that it is handled
+                                            res.innerText = "";
+                                            _prepareCallback(message, "messageReceived", 200, rq.transport);
+                                        }
                                         rq.lastIndex = 0;
                                     }
 
@@ -1938,12 +1910,13 @@ jQuery.atmosphere = function() {
 
                                 return false;
                             } catch (err) {
+                                _response.error = true;
                                 if (_requestCount++ < rq.maxReconnectOnClose) {
                                     rq.id = setTimeout(function() {
                                         _ieStreaming(rq);
                                     }, rq.reconnectInterval);
                                 } else {
-                                    _onError();
+                                    _onError(0, "maxReconnectOnClose reached");
                                 }
                                 doc.execCommand("Stop");
                                 doc.close();
@@ -2095,6 +2068,7 @@ jQuery.atmosphere = function() {
                     attachHeadersAsQueryString: true,
                     enableXDR: _request.enableXDR,
                     uuid : _request.uuid,
+                    messageDelimiter : '|',
                     enableProtocol : false,
                     maxReconnectOnClose : _request.maxReconnectOnClose
                 };
@@ -2147,11 +2121,11 @@ jQuery.atmosphere = function() {
             }
 
             function _prepareCallback(messageBody, state, errorCode, transport) {
-               _response.responseBody = messageBody;
+
                 if (state == "messageReceived") {
-                    if (_trackMessageSize(messageBody, _request, _response)) {
-                       return;
-                    }
+                    if (_trackMessageSize(messageBody, _request, _response)) return;
+                } else {
+                    _response.responseBody = messageBody;
                 }
 
                 _response.transport = transport;
@@ -2225,6 +2199,14 @@ jQuery.atmosphere = function() {
                 }
             }
 
+            function _invokeClose(wasOpen) {
+                _response.state = 'closed';
+                _response.responseBody = "";
+                _response.messages = [];
+                _response.status = !wasOpen ? 501 : 200;
+                _invokeCallback();
+            }
+
             /**
              * Invoke request callbacks.
              *
@@ -2242,7 +2224,7 @@ jQuery.atmosphere = function() {
                 _request.reconnect = _request.mrequest;
 
                 var messages = (typeof(_response.responseBody) == 'string' && _request.trackMessageLength) ?
-                    _response.responseBody.split(_request.messageDelimiter) : new Array(_response.responseBody);
+                    (_response.messages.length>0 ? _response.messages : ['']) : new Array(_response.responseBody);
                 for (var i = 0; i < messages.length; i++) {
 
                     if (messages.length > 1 && messages[i].length == 0) {
@@ -2250,13 +2232,8 @@ jQuery.atmosphere = function() {
                     }
                     _response.responseBody = jQuery.trim(messages[i]);
 
-                    // Ugly see issue 400.
-                    if (_response.responseBody.length == 0 && _response.transport == 'streaming' && _response.state == "messageReceived") {
-                        var ua = navigator.userAgent.toLowerCase();
-                        var isAndroid = ua.indexOf("android") > -1;
-                        if (isAndroid) {
-                            continue;
-                        }
+                    if (_response.responseBody.length == 0 && _response.state == "messageReceived") {
+                        continue;
                     }
 
                     _invokeFunction(_response);
@@ -2288,17 +2265,53 @@ jQuery.atmosphere = function() {
 
             }
 
+            /**
+             *
+             * @private
+             */
+            function _verifyStreamingLength(ajaxRequest, rq){
+                // Wait to be sure we have the full message before closing.
+                if (_response.partialMessage == "" &&
+                        (rq.transport == 'streaming') &&
+                        (ajaxRequest.responseText.length > rq.maxStreamingLength)) {
+                    _response.messages = [];
+                    _invokeClose(true);
+                    _disconnect();
+                    _clearState();
+                    _reconnect(ajaxRequest, rq, true);
+                }
+            }
+
+            /**
+             * Disconnect
+             * @private
+             */
+            function _disconnect() {
+                if (_request.enableProtocol) {
+                    var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + _request.uuid;
+                    var url = _request.url.replace(/([?&])_=[^&]*/, query);
+                    url = url + (url === _request.url ? (/\?/.test(_request.url) ? "&" : "?") + query : "");
+
+                    if (_request.connectTimeout > -1) {
+                        jQuery.ajax({url: url, async: false, timeout: _request.connectTimeout});
+                    } else {
+                        jQuery.ajax({url: url, async: false});
+                    }
+                }
+            }
+
             /**
              * Close request.
              *
              * @private
              */
             function _close() {
-                _abordingConnection = true;
                 _request.reconnect = false;
+                _abordingConnection = true;
                 _response.request = _request;
                 _response.state = 'unsubscribe';
                 _response.responseBody = "";
+                _response.messages = [];
                 _response.status = 408;
                 _invokeCallback();
 
@@ -2319,7 +2332,9 @@ jQuery.atmosphere = function() {
                     _activeRequest = null;
                 }
                 if (_websocket != null) {
-                    _websocket.close();
+                    if (_websocket.webSocketOpened) {
+                        _websocket.close();
+                    }
                     _websocket = null;
                 }
                 if (_sse != null) {
@@ -2343,7 +2358,7 @@ jQuery.atmosphere = function() {
                 if (_localStorageService != null) {
                     _localStorageService.close();
                 }
-            }
+            };
 
             this.subscribe = function(options) {
                 _subscribe(options);
@@ -2362,6 +2377,10 @@ jQuery.atmosphere = function() {
                 _close();
             };
 
+            this.disconnect = function () {
+                _disconnect();
+            };
+
             this.getUrl = function() {
                 return _request.url;
             };
@@ -2421,10 +2440,8 @@ jQuery.atmosphere = function() {
               var requestsClone = [].concat(jQuery.atmosphere.requests);
               for (var i = 0; i < requestsClone.length; i++) {
                     var rq = requestsClone[i];
+                    rq.disconnect();
                     rq.close();
-                    if (rq.enableProtocol()) {
-                        jQuery.ajax({url: this._closeUrl(rq), async:false});
-                    }
                     clearTimeout(rq.response.request.id);
                 }
             }
@@ -2432,12 +2449,6 @@ jQuery.atmosphere = function() {
             jQuery.atmosphere.callbacks = [];
         },
 
-        _closeUrl : function(rq) {
-            var query = "X-Atmosphere-Transport=close&X-Atmosphere-tracking-id=" + rq.getUUID();
-            var url = rq.getUrl().replace(/([?&])_=[^&]*/, query);
-            return url + (url === rq.getUrl() ? (/\?/.test(rq.getUrl()) ? "&" : "?") + query : "");
-        },
-
         unsubscribeUrl: function(url) {
             var idx = -1;
             if (jQuery.atmosphere.requests.length > 0) {
@@ -2446,10 +2457,8 @@ jQuery.atmosphere = function() {
 
                     // Suppose you can subscribe once to an url
                     if (rq.getUrl() == url) {
+                        rq.disconnect();
                         rq.close();
-                        if (rq.enableProtocol()) {
-                            jQuery.ajax({url :this._closeUrl(rq), async:false});
-                        }
                         clearTimeout(rq.response.request.id);
                         idx = i;
                         break;
@@ -2643,8 +2652,8 @@ jQuery.atmosphere = function() {
 /*
  * jQuery stringifyJSON
  * http://github.com/flowersinthesand/jquery-stringifyJSON
- * 
- * Copyright 2011, Donghwan Kim 
+ *
+ * Copyright 2011, Donghwan Kim
  * Licensed under the Apache License, Version 2.0
  * http://www.apache.org/licenses/LICENSE-2.0
  */
@@ -2728,4 +2737,4 @@ jQuery.atmosphere = function() {
         return str("", {"": value});
     };
 
-}(jQuery));
\ No newline at end of file
+}(jQuery));
index d06b946dd10a028979b12809c7a133ef9692468f..953416cf2ddb7eb4e82dc771f275072d90423d34 100644 (file)
@@ -13,7 +13,7 @@
        <property name="vaadinPush.js" location="${result.dir}/js/VAADIN/vaadinPush.js" />
 
        <!-- Keep the version number in sync with ivy.xml -->
-       <property name="atmosphere.version" value="1.0.12" />
+       <property name="atmosphere.version" value="1.0.13" />
        <property name="jquery.version" value="1.7.2" />
 
        <path id="classpath.compile.custom" />
@@ -62,7 +62,6 @@
                <antcall target="common.sources.jar">
                        <reference torefid="extra.jar.includes" refid="jar.includes" />
                </antcall>
-               <antcall target="common.javadoc.jar" />
                <antcall target="common.publish-local" />
        </target>
 
index a5ca79d4a39bf9a7c0f9492f6a0d9d423734297d..4834342f0062826b702ef4de7b23e85fdb1fbb12 100644 (file)
@@ -28,7 +28,7 @@
                        
         <!-- Atmosphere -->
         <!-- Keep the version number in sync with build.xml -->
-        <dependency org="org.atmosphere" name="atmosphere-runtime" rev="1.0.12"
+        <dependency org="org.atmosphere" name="atmosphere-runtime" rev="1.0.13"
                conf="build,ide,test -> default">
         </dependency>
     </dependencies>
diff --git a/push/src/org/atmosphere/cpr/AtmosphereFramework.java b/push/src/org/atmosphere/cpr/AtmosphereFramework.java
deleted file mode 100644 (file)
index 62f867f..0000000
+++ /dev/null
@@ -1,1779 +0,0 @@
-/*
- * Copyright 2013 Jeanfrancois Arcand
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package org.atmosphere.cpr;
-
-import org.atmosphere.cache.UUIDBroadcasterCache;
-import org.atmosphere.config.ApplicationConfiguration;
-import org.atmosphere.config.AtmosphereHandlerConfig;
-import org.atmosphere.config.AtmosphereHandlerProperty;
-import org.atmosphere.config.FrameworkConfiguration;
-import org.atmosphere.container.BlockingIOCometSupport;
-import org.atmosphere.container.Tomcat7BIOSupportWithWebSocket;
-import org.atmosphere.di.InjectorProvider;
-import org.atmosphere.di.ServletContextHolder;
-import org.atmosphere.di.ServletContextProvider;
-import org.atmosphere.handler.AbstractReflectorAtmosphereHandler;
-import org.atmosphere.handler.ReflectorServletProcessor;
-import org.atmosphere.interceptor.AndroidAtmosphereInterceptor;
-import org.atmosphere.interceptor.JSONPAtmosphereInterceptor;
-import org.atmosphere.interceptor.JavaScriptProtocol;
-import org.atmosphere.interceptor.OnDisconnectInterceptor;
-import org.atmosphere.interceptor.SSEAtmosphereInterceptor;
-import org.atmosphere.util.AtmosphereConfigReader;
-import org.atmosphere.util.IntrospectionUtils;
-import org.atmosphere.util.Version;
-import org.atmosphere.websocket.DefaultWebSocketProcessor;
-import org.atmosphere.websocket.WebSocket;
-import org.atmosphere.websocket.WebSocketProtocol;
-import org.atmosphere.websocket.protocol.SimpleHttpProtocol;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import static org.atmosphere.cpr.ApplicationConfig.ALLOW_QUERYSTRING_AS_REQUEST;
-import static org.atmosphere.cpr.ApplicationConfig.ATMOSPHERE_HANDLER;
-import static org.atmosphere.cpr.ApplicationConfig.ATMOSPHERE_HANDLER_MAPPING;
-import static org.atmosphere.cpr.ApplicationConfig.ATMOSPHERE_HANDLER_PATH;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_CACHE;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_CLASS;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_FACTORY;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCASTER_LIFECYCLE_POLICY;
-import static org.atmosphere.cpr.ApplicationConfig.BROADCAST_FILTER_CLASSES;
-import static org.atmosphere.cpr.ApplicationConfig.DISABLE_ONSTATE_EVENT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_ATMOSPHERE_XML;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_BLOCKING_COMETSUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_COMET_SUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_NATIVE_COMETSUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_SERVLET_MAPPING;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_SESSION_SUPPORT;
-import static org.atmosphere.cpr.ApplicationConfig.PROPERTY_USE_STREAM;
-import static org.atmosphere.cpr.ApplicationConfig.RESUME_AND_KEEPALIVE;
-import static org.atmosphere.cpr.ApplicationConfig.SUSPENDED_ATMOSPHERE_RESOURCE_UUID;
-import static org.atmosphere.cpr.ApplicationConfig.WEBSOCKET_PROCESSOR;
-import static org.atmosphere.cpr.ApplicationConfig.WEBSOCKET_PROTOCOL;
-import static org.atmosphere.cpr.ApplicationConfig.WEBSOCKET_SUPPORT;
-import static org.atmosphere.cpr.FrameworkConfig.ATMOSPHERE_CONFIG;
-import static org.atmosphere.cpr.FrameworkConfig.HAZELCAST_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.JERSEY_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.JERSEY_CONTAINER;
-import static org.atmosphere.cpr.FrameworkConfig.JGROUPS_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.JMS_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.REDIS_BROADCASTER;
-import static org.atmosphere.cpr.FrameworkConfig.WRITE_HEADERS;
-import static org.atmosphere.cpr.FrameworkConfig.XMPP_BROADCASTER;
-import static org.atmosphere.cpr.HeaderConfig.ATMOSPHERE_POST_BODY;
-import static org.atmosphere.cpr.HeaderConfig.X_ATMOSPHERE_TRACKING_ID;
-import static org.atmosphere.websocket.WebSocket.WEBSOCKET_SUSPEND;
-
-/**
- * The {@link AtmosphereFramework} is the entry point for the framework. This class can be used to from Servlet/filter
- * to dispatch {@link AtmosphereRequest} and {@link AtmosphereResponse}. The framework can also be configured using
- * the setXXX method. The life cycle of this class is
- * <blockquote><pre>
- * AtmosphereFramework f = new AtmosphereFramework();
- * f.init();
- * f.doCometSupport(AtmosphereRequest, AtmosphereResource);
- * f.destroy();
- * </pre></blockquote>
- *
- * @author Jeanfrancois Arcand
- */
-public class AtmosphereFramework implements ServletContextProvider {
-    public static final String DEFAULT_ATMOSPHERE_CONFIG_PATH = "/META-INF/atmosphere.xml";
-    public static final String DEFAULT_LIB_PATH = "/WEB-INF/lib/";
-    public static final String MAPPING_REGEX = "[a-zA-Z0-9-&.*=@~;\\?]+";
-
-    protected static final Logger logger = LoggerFactory.getLogger(AtmosphereFramework.class);
-
-    protected final List<String> broadcasterFilters = new ArrayList<String>();
-    protected final List<AsyncSupportListener> asyncSupportListeners = new ArrayList<AsyncSupportListener>();
-    protected final ArrayList<String> possibleComponentsCandidate = new ArrayList<String>();
-    protected final HashMap<String, String> initParams = new HashMap<String, String>();
-    protected final AtmosphereConfig config;
-    protected final AtomicBoolean isCometSupportConfigured = new AtomicBoolean(false);
-    protected final boolean isFilter;
-    protected final Map<String, AtmosphereHandlerWrapper> atmosphereHandlers = new ConcurrentHashMap<String, AtmosphereHandlerWrapper>();
-    protected final ConcurrentLinkedQueue<String> broadcasterTypes = new ConcurrentLinkedQueue<String>();
-
-    protected boolean useNativeImplementation = false;
-    protected boolean useBlockingImplementation = false;
-    protected boolean useStreamForFlushingComments = false;
-    protected AsyncSupport asyncSupport;
-    protected String broadcasterClassName = DefaultBroadcaster.class.getName();
-    protected boolean isCometSupportSpecified = false;
-    protected boolean isBroadcasterSpecified = false;
-    protected boolean isSessionSupportSpecified = false;
-    protected BroadcasterFactory broadcasterFactory;
-    protected String broadcasterFactoryClassName;
-    protected String broadcasterCacheClassName;
-    protected boolean webSocketEnabled = true;
-    protected String broadcasterLifeCyclePolicy = "NEVER";
-    protected String webSocketProtocolClassName = SimpleHttpProtocol.class.getName();
-    protected WebSocketProtocol webSocketProtocol;
-    protected String handlersPath = "/WEB-INF/classes/";
-    protected ServletConfig servletConfig;
-    protected boolean autoDetectHandlers = true;
-    private boolean hasNewWebSocketProtocol = false;
-    protected String atmosphereDotXmlPath = DEFAULT_ATMOSPHERE_CONFIG_PATH;
-    protected final LinkedList<AtmosphereInterceptor> interceptors = new LinkedList<AtmosphereInterceptor>();
-    protected boolean scanDone = false;
-    protected String annotationProcessorClassName = "org.atmosphere.cpr.DefaultAnnotationProcessor";
-    protected final List<BroadcasterListener> broadcasterListeners = new ArrayList<BroadcasterListener>();
-    protected String webSocketProcessorClassName = DefaultWebSocketProcessor.class.getName();
-    protected String libPath = DEFAULT_LIB_PATH;
-    protected boolean isInit;
-    protected boolean sharedThreadPools = true;
-
-    public static final class AtmosphereHandlerWrapper {
-
-        public final AtmosphereHandler atmosphereHandler;
-        public Broadcaster broadcaster;
-        public String mapping;
-        public List<AtmosphereInterceptor> interceptors = Collections.<AtmosphereInterceptor>emptyList();
-
-        public AtmosphereHandlerWrapper(BroadcasterFactory broadcasterFactory, AtmosphereHandler atmosphereHandler, String mapping) {
-            this.atmosphereHandler = atmosphereHandler;
-            try {
-                if (broadcasterFactory != null) {
-                    this.broadcaster = broadcasterFactory.lookup(mapping, true);
-                } else {
-                    this.mapping = mapping;
-                }
-            } catch (Exception t) {
-                throw new RuntimeException(t);
-            }
-        }
-
-        public AtmosphereHandlerWrapper(AtmosphereHandler atmosphereHandler, Broadcaster broadcaster) {
-            this.atmosphereHandler = atmosphereHandler;
-            this.broadcaster = broadcaster;
-        }
-
-        @Override
-        public String toString() {
-            return "AtmosphereHandlerWrapper{ atmosphereHandler=" + atmosphereHandler + ", broadcaster=" +
-                    broadcaster + " }";
-        }
-    }
-
-    /**
-     * Create an AtmosphereFramework.
-     */
-    public AtmosphereFramework() {
-        this(false, true);
-    }
-
-    /**
-     * Create an AtmosphereFramework and initialize it via {@link AtmosphereFramework#init(javax.servlet.ServletConfig)}
-     */
-    public AtmosphereFramework(ServletConfig sc) throws ServletException {
-        this(false, true);
-        init(sc);
-    }
-
-    /**
-     * Create an AtmosphereFramework.
-     *
-     * @param isFilter true if this instance is used as an {@link AtmosphereFilter}
-     */
-    public AtmosphereFramework(boolean isFilter, boolean autoDetectHandlers) {
-        this.isFilter = isFilter;
-        this.autoDetectHandlers = autoDetectHandlers;
-        readSystemProperties();
-        populateBroadcasterType();
-        config = new AtmosphereConfig(this);
-    }
-
-    /**
-     * The order of addition is quite important here.
-     */
-    private void populateBroadcasterType() {
-        broadcasterTypes.add(HAZELCAST_BROADCASTER);
-        broadcasterTypes.add(XMPP_BROADCASTER);
-        broadcasterTypes.add(REDIS_BROADCASTER);
-        broadcasterTypes.add(JGROUPS_BROADCASTER);
-        broadcasterTypes.add(JMS_BROADCASTER);
-    }
-
-    /**
-     * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
-     * This API is exposed to allow embedding an Atmosphere application.
-     *
-     * @param mapping The servlet mapping (servlet path)
-     * @param h       implementation of an {@link AtmosphereHandler}
-     * @param l       An attay of {@link AtmosphereInterceptor}
-     */
-    public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, List<AtmosphereInterceptor> l) {
-        if (!mapping.startsWith("/")) {
-            mapping = "/" + mapping;
-        }
-
-        AtmosphereHandlerWrapper w = new AtmosphereHandlerWrapper(broadcasterFactory, h, mapping);
-        w.interceptors = l;
-        addMapping(mapping, w);
-
-        logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", h.getClass().getName(), mapping);
-        if (l.size() > 0) {
-            logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, h.getClass().getName());
-        }
-        return this;
-    }
-
-    /**
-     * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
-     * This API is exposed to allow embedding an Atmosphere application.
-     *
-     * @param mapping The servlet mapping (servlet path)
-     * @param h       implementation of an {@link AtmosphereHandler}
-     */
-    public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h) {
-        addAtmosphereHandler(mapping, h, Collections.<AtmosphereInterceptor>emptyList());
-        return this;
-    }
-
-    private AtmosphereFramework addMapping(String path, AtmosphereHandlerWrapper w) {
-        // We are using JAXRS mapping algorithm.
-        if (path.contains("*")) {
-            path = path.replace("*", MAPPING_REGEX);
-        }
-
-        if (path.endsWith("/")) {
-            path = path + MAPPING_REGEX;
-        }
-
-        InjectorProvider.getInjector().inject(w.atmosphereHandler);
-        atmosphereHandlers.put(path, w);
-        return this;
-    }
-
-    /**
-     * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
-     * This API is exposed to allow embedding an Atmosphere application.
-     *
-     * @param mapping       The servlet mapping (servlet path)
-     * @param h             implementation of an {@link AtmosphereHandler}
-     * @param broadcasterId The {@link Broadcaster#getID} value.
-     * @param l             An attay of {@link AtmosphereInterceptor}
-     */
-    public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, String broadcasterId, List<AtmosphereInterceptor> l) {
-        if (!mapping.startsWith("/")) {
-            mapping = "/" + mapping;
-        }
-
-        AtmosphereHandlerWrapper w = new AtmosphereHandlerWrapper(broadcasterFactory, h, mapping);
-        w.broadcaster.setID(broadcasterId);
-        w.interceptors = l;
-        addMapping(mapping, w);
-        logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", h.getClass().getName(), mapping);
-        if (l.size() > 0) {
-            logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, h.getClass().getName());
-        }
-        return this;
-    }
-
-    /**
-     * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
-     * This API is exposed to allow embedding an Atmosphere application.
-     *
-     * @param mapping       The servlet mapping (servlet path)
-     * @param h             implementation of an {@link AtmosphereHandler}
-     * @param broadcasterId The {@link Broadcaster#getID} value.
-     */
-    public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, String broadcasterId) {
-        addAtmosphereHandler(mapping, h, broadcasterId, Collections.<AtmosphereInterceptor>emptyList());
-        return this;
-    }
-
-    /**
-     * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
-     * This API is exposed to allow embedding an Atmosphere application.
-     *
-     * @param mapping     The servlet mapping (servlet path)
-     * @param h           implementation of an {@link AtmosphereHandler}
-     * @param broadcaster The {@link Broadcaster} associated with AtmosphereHandler.
-     * @param l           An attay of {@link AtmosphereInterceptor}
-     */
-    public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, Broadcaster broadcaster, List<AtmosphereInterceptor> l) {
-        if (!mapping.startsWith("/")) {
-            mapping = "/" + mapping;
-        }
-
-        AtmosphereHandlerWrapper w = new AtmosphereHandlerWrapper(h, broadcaster);
-        w.interceptors = l;
-
-        addMapping(mapping, w);
-        logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", h.getClass().getName(), mapping);
-        if (l.size() > 0) {
-            logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, h.getClass().getName());
-        }
-        return this;
-    }
-
-    /**
-     * Add an {@link AtmosphereHandler} serviced by the {@link Servlet}
-     * This API is exposed to allow embedding an Atmosphere application.
-     *
-     * @param mapping     The servlet mapping (servlet path)
-     * @param h           implementation of an {@link AtmosphereHandler}
-     * @param broadcaster The {@link Broadcaster} associated with AtmosphereHandler.
-     */
-    public AtmosphereFramework addAtmosphereHandler(String mapping, AtmosphereHandler h, Broadcaster broadcaster) {
-        addAtmosphereHandler(mapping, h, broadcaster, Collections.<AtmosphereInterceptor>emptyList());
-        return this;
-    }
-
-    /**
-     * Remove an {@link AtmosphereHandler}
-     *
-     * @param mapping the mapping used when invoking {@link #addAtmosphereHandler(String, AtmosphereHandler)};
-     * @return true if removed
-     */
-    public AtmosphereFramework removeAtmosphereHandler(String mapping) {
-
-        if (mapping.endsWith("/")) {
-            mapping += MAPPING_REGEX;
-        }
-
-        atmosphereHandlers.remove(mapping);
-        return this;
-    }
-
-    /**
-     * Remove all {@link AtmosphereHandler}
-     */
-    public AtmosphereFramework removeAllAtmosphereHandler() {
-        atmosphereHandlers.clear();
-        return this;
-    }
-
-    /**
-     * Remove all init parameters.
-     */
-    public AtmosphereFramework removeAllInitParams() {
-        initParams.clear();
-        return this;
-    }
-
-    /**
-     * Add init-param like if they were defined in web.xml
-     *
-     * @param name  The name
-     * @param value The value
-     */
-    public AtmosphereFramework addInitParameter(String name, String value) {
-        initParams.put(name, value);
-        return this;
-    }
-
-    protected void readSystemProperties() {
-        if (System.getProperty(PROPERTY_NATIVE_COMETSUPPORT) != null) {
-            useNativeImplementation = Boolean
-                    .parseBoolean(System.getProperty(PROPERTY_NATIVE_COMETSUPPORT));
-            isCometSupportSpecified = true;
-        }
-
-        if (System.getProperty(PROPERTY_BLOCKING_COMETSUPPORT) != null) {
-            useBlockingImplementation = Boolean
-                    .parseBoolean(System.getProperty(PROPERTY_BLOCKING_COMETSUPPORT));
-            isCometSupportSpecified = true;
-        }
-        atmosphereDotXmlPath = System.getProperty(PROPERTY_ATMOSPHERE_XML, atmosphereDotXmlPath);
-
-        if (System.getProperty(DISABLE_ONSTATE_EVENT) != null) {
-            initParams.put(DISABLE_ONSTATE_EVENT, System.getProperty(DISABLE_ONSTATE_EVENT));
-        }
-    }
-
-    /**
-     * Path specific container using their own property.
-     */
-    public void patchContainer() {
-        System.setProperty("org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "false");
-    }
-
-    /**
-     * Initialize the AtmosphereFramework. Invoke that method after having properly configured this class using the setter.
-     */
-    public AtmosphereFramework init() {
-        try {
-            init(new ServletConfig() {
-
-                @Override
-                public String getServletName() {
-                    return "AtmosphereFramework";
-                }
-
-                @Override
-                public ServletContext getServletContext() {
-                    return (ServletContext) Proxy.newProxyInstance(getClass().getClassLoader(), new Class[]{ServletContext.class},
-                            new InvocationHandler() {
-                                @Override
-                                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                                    logger.trace("Method {} not supported", method.getName());
-                                    return null;
-                                }
-                            });
-                }
-
-                @Override
-                public String getInitParameter(String name) {
-                    return initParams.get(name);
-                }
-
-                @Override
-                public Enumeration<String> getInitParameterNames() {
-                    return Collections.enumeration(initParams.values());
-                }
-            });
-        } catch (ServletException e) {
-            logger.error("", e);
-        }
-        return this;
-    }
-
-    /**
-     * Initialize the AtmosphereFramework using the {@link ServletContext}
-     *
-     * @param sc the {@link ServletContext}
-     */
-    public AtmosphereFramework init(final ServletConfig sc) throws ServletException {
-
-        if (isInit) return this;
-
-        try {
-            ServletContextHolder.register(this);
-
-            ServletConfig scFacade = new ServletConfig() {
-
-                public String getServletName() {
-                    return sc.getServletName();
-                }
-
-                public ServletContext getServletContext() {
-                    return sc.getServletContext();
-                }
-
-                public String getInitParameter(String name) {
-                    String param = initParams.get(name);
-                    if (param == null) {
-                        return sc.getInitParameter(name);
-                    }
-                    return param;
-                }
-
-                public Enumeration<String> getInitParameterNames() {
-                    Enumeration en = sc.getInitParameterNames();
-                    while (en.hasMoreElements()) {
-                        String name = (String) en.nextElement();
-                        if (!initParams.containsKey(name)) {
-                            initParams.put(name, sc.getInitParameter(name));
-                        }
-                    }
-                    return Collections.enumeration(initParams.keySet());
-                }
-            };
-            this.servletConfig = scFacade;
-            asyncSupportListener(new AsyncSupportListenerAdapter());
-
-            autoConfigureService(scFacade.getServletContext());
-            patchContainer();
-            doInitParams(scFacade);
-            doInitParamsForWebSocket(scFacade);
-            configureBroadcaster();
-            loadConfiguration(scFacade);
-            initWebSocket();
-
-            autoDetectContainer();
-            configureWebDotXmlAtmosphereHandler(sc);
-            asyncSupport.init(scFacade);
-            initAtmosphereHandler(scFacade);
-            configureAtmosphereInterceptor(sc);
-
-            if (broadcasterCacheClassName == null) {
-                logger.warn("No BroadcasterCache configured. Broadcasted message between client reconnection will be LOST. " +
-                        "It is recommended to configure the {}", UUIDBroadcasterCache.class.getName());
-            } else {
-                logger.info("Using BroadcasterCache: {}", broadcasterCacheClassName);
-            }
-
-            // http://java.net/jira/browse/ATMOSPHERE-157
-            if (sc.getServletContext() != null) {
-                sc.getServletContext().setAttribute(BroadcasterFactory.class.getName(), broadcasterFactory);
-            }
-
-            for (String i : broadcasterFilters) {
-                logger.info("Using BroadcastFilter: {}", i);
-            }
-
-            String s = config.getInitParameter(ApplicationConfig.BROADCASTER_SHARABLE_THREAD_POOLS);
-            if (s != null) {
-                sharedThreadPools = Boolean.parseBoolean(s);
-            }
-
-            logger.info("Shared ExecutorService supported: {}", sharedThreadPools);
-            logger.info("HttpSession supported: {}", config.isSupportSession());
-            logger.info("Using BroadcasterFactory: {}", broadcasterFactory.getClass().getName());
-            logger.info("Using WebSocketProcessor: {}", webSocketProcessorClassName);
-            logger.info("Using Broadcaster: {}", broadcasterClassName);
-            logger.info("Atmosphere Framework {} started.", Version.getRawVersion());
-
-            String showSupportMessage = config.getInitParameter("org.atmosphere.cpr.showSupportMessage");
-            if (showSupportMessage == null || Boolean.parseBoolean(showSupportMessage)) {
-                logger.info("\n\n\tFor Commercial Support, visit \n\t{} " +
-                        "or send an email to {}\n", "http://www.async-io.org/", "support@async-io.org");
-            }
-        } catch (Throwable t) {
-            logger.error("Failed to initialize Atmosphere Framework", t);
-
-            if (t instanceof ServletException) {
-                throw (ServletException) t;
-            }
-
-            throw new ServletException(t);
-        }
-        isInit = true;
-        return this;
-    }
-
-    /**
-     * Configure the list of {@link AtmosphereInterceptor}.
-     *
-     * @param sc a ServletConfig
-     */
-    protected void configureAtmosphereInterceptor(ServletConfig sc) {
-        String s = sc.getInitParameter(ApplicationConfig.ATMOSPHERE_INTERCEPTORS);
-        if (s != null) {
-            String[] list = s.split(",");
-            for (String a : list) {
-                try {
-                    AtmosphereInterceptor ai = (AtmosphereInterceptor) Thread.currentThread().getContextClassLoader()
-                            .loadClass(a.trim()).newInstance();
-                    ai.configure(config);
-                    interceptor(ai);
-                } catch (InstantiationException e) {
-                    logger.warn("", e);
-                } catch (IllegalAccessException e) {
-                    logger.warn("", e);
-                } catch (ClassNotFoundException e) {
-                    logger.warn("", e);
-                }
-            }
-        }
-
-        s = sc.getInitParameter(ApplicationConfig.DISABLE_ATMOSPHEREINTERCEPTOR);
-        if (s == null) {
-            // OnDisconnect
-            interceptors.addFirst(newAInterceptor(OnDisconnectInterceptor.class));
-            // ADD Tracking ID Handshake
-            interceptors.addFirst(newAInterceptor(JavaScriptProtocol.class));
-            // ADD JSONP support
-            interceptors.addFirst(newAInterceptor(JSONPAtmosphereInterceptor.class));
-            // Add SSE support
-            interceptors.addFirst(newAInterceptor(SSEAtmosphereInterceptor.class));
-            // Android 2.3.x streaming support
-            interceptors.addFirst(newAInterceptor(AndroidAtmosphereInterceptor.class));
-            logger.info("Installed Default AtmosphereInterceptor {}. " +
-                    "Set org.atmosphere.cpr.AtmosphereInterceptor.disableDefaults in your xml to disable them.", interceptors);
-        }
-    }
-
-    protected AtmosphereInterceptor newAInterceptor(Class<? extends AtmosphereInterceptor> a) {
-        AtmosphereInterceptor ai = null;
-        try {
-            ai = (AtmosphereInterceptor) getClass().getClassLoader().loadClass(a.getName()).newInstance();
-            ai.configure(config);
-        } catch (Exception ex) {
-            logger.warn("", ex);
-        }
-        return ai;
-    }
-
-    protected void configureWebDotXmlAtmosphereHandler(ServletConfig sc) {
-        String s = sc.getInitParameter(ATMOSPHERE_HANDLER);
-        if (s != null) {
-            ClassLoader cl = Thread.currentThread().getContextClassLoader();
-            try {
-
-                String mapping = sc.getInitParameter(ATMOSPHERE_HANDLER_MAPPING);
-                if (mapping == null) {
-                    mapping = "/*";
-                }
-                addAtmosphereHandler(mapping, (AtmosphereHandler) cl.loadClass(s).newInstance());
-            } catch (Exception ex) {
-                logger.warn("Unable to load WebSocketHandle instance", ex);
-            }
-        }
-    }
-
-    protected void configureBroadcaster() {
-
-        try {
-            // Check auto supported one
-            if (isBroadcasterSpecified == false) {
-                broadcasterClassName = lookupDefaultBroadcasterType(broadcasterClassName);
-            }
-
-            Class<? extends Broadcaster> bc =
-                    (Class<? extends Broadcaster>) Thread.currentThread().getContextClassLoader()
-                            .loadClass(broadcasterClassName);
-            if (broadcasterFactoryClassName != null) {
-                broadcasterFactory = (BroadcasterFactory) Thread.currentThread().getContextClassLoader()
-                        .loadClass(broadcasterFactoryClassName).newInstance();
-            }
-
-            if (broadcasterFactory == null) {
-                broadcasterFactory = new DefaultBroadcasterFactory(bc, broadcasterLifeCyclePolicy, config);
-            }
-
-            for (BroadcasterListener b : broadcasterListeners) {
-                broadcasterFactory.addBroadcasterListener(b);
-            }
-
-            BroadcasterFactory.setBroadcasterFactory(broadcasterFactory, config);
-            InjectorProvider.getInjector().inject(broadcasterFactory);
-
-            Iterator<Entry<String, AtmosphereHandlerWrapper>> i = atmosphereHandlers.entrySet().iterator();
-            AtmosphereHandlerWrapper w;
-            Entry<String, AtmosphereHandlerWrapper> e;
-            while (i.hasNext()) {
-                e = i.next();
-                w = e.getValue();
-
-                if (w.broadcaster == null) {
-                    w.broadcaster = broadcasterFactory.get(w.mapping);
-                } else {
-                    if (broadcasterCacheClassName != null) {
-                        BroadcasterCache cache = (BroadcasterCache) Thread.currentThread().getContextClassLoader()
-                                .loadClass(broadcasterCacheClassName).newInstance();
-                        InjectorProvider.getInjector().inject(cache);
-                        w.broadcaster.getBroadcasterConfig().setBroadcasterCache(cache);
-                    }
-                }
-            }
-        } catch (Exception ex) {
-            logger.error("Unable to configure Broadcaster/Factory/Cache", ex);
-        }
-    }
-
-    protected void doInitParamsForWebSocket(ServletConfig sc) {
-        String s = sc.getInitParameter(WEBSOCKET_SUPPORT);
-        if (s != null) {
-            webSocketEnabled = Boolean.parseBoolean(s);
-            sessionSupport(false);
-        }
-        s = sc.getInitParameter(WEBSOCKET_PROTOCOL);
-        if (s != null) {
-            webSocketProtocolClassName = s;
-        }
-
-        s = sc.getInitParameter(WEBSOCKET_PROCESSOR);
-        if (s != null) {
-            webSocketProcessorClassName = s;
-        }
-    }
-
-    /**
-     * Read init param from web.xml and apply them.
-     *
-     * @param sc {@link ServletConfig}
-     */
-    protected void doInitParams(ServletConfig sc) {
-        String s = sc.getInitParameter(PROPERTY_NATIVE_COMETSUPPORT);
-        if (s != null) {
-            useNativeImplementation = Boolean.parseBoolean(s);
-            if (useNativeImplementation) isCometSupportSpecified = true;
-        }
-        s = sc.getInitParameter(PROPERTY_BLOCKING_COMETSUPPORT);
-        if (s != null) {
-            useBlockingImplementation = Boolean.parseBoolean(s);
-            if (useBlockingImplementation) isCometSupportSpecified = true;
-        }
-        s = sc.getInitParameter(PROPERTY_USE_STREAM);
-        if (s != null) {
-            useStreamForFlushingComments = Boolean.parseBoolean(s);
-        }
-        s = sc.getInitParameter(PROPERTY_COMET_SUPPORT);
-        if (s != null) {
-            asyncSupport = new DefaultAsyncSupportResolver(config).newCometSupport(s);
-            isCometSupportSpecified = true;
-        }
-        s = sc.getInitParameter(BROADCASTER_CLASS);
-        if (s != null) {
-            broadcasterClassName = s;
-            isBroadcasterSpecified = true;
-        }
-        s = sc.getInitParameter(BROADCASTER_CACHE);
-        if (s != null) {
-            broadcasterCacheClassName = s;
-        }
-        s = sc.getInitParameter(PROPERTY_SESSION_SUPPORT);
-        if (s != null) {
-            config.setSupportSession(Boolean.valueOf(s));
-            isSessionSupportSpecified = true;
-        }
-        s = sc.getInitParameter(DISABLE_ONSTATE_EVENT);
-        if (s != null) {
-            initParams.put(DISABLE_ONSTATE_EVENT, s);
-        } else {
-            initParams.put(DISABLE_ONSTATE_EVENT, "false");
-        }
-        s = sc.getInitParameter(RESUME_AND_KEEPALIVE);
-        if (s != null) {
-            initParams.put(RESUME_AND_KEEPALIVE, s);
-        }
-        s = sc.getInitParameter(BROADCAST_FILTER_CLASSES);
-        if (s != null) {
-            broadcasterFilters.addAll(Arrays.asList(s.split(",")));
-            logger.info("Installing BroadcastFilter class(es) {}", s);
-        }
-        s = sc.getInitParameter(BROADCASTER_LIFECYCLE_POLICY);
-        if (s != null) {
-            broadcasterLifeCyclePolicy = s;
-        }
-        s = sc.getInitParameter(BROADCASTER_FACTORY);
-        if (s != null) {
-            broadcasterFactoryClassName = s;
-        }
-        s = sc.getInitParameter(ATMOSPHERE_HANDLER_PATH);
-        if (s != null) {
-            handlersPath = s;
-        }
-        s = sc.getInitParameter(PROPERTY_ATMOSPHERE_XML);
-        if (s != null) {
-            atmosphereDotXmlPath = s;
-        }
-    }
-
-    public void loadConfiguration(ServletConfig sc) throws ServletException {
-
-        if (!autoDetectHandlers) return;
-
-        try {
-            URL url = sc.getServletContext().getResource(handlersPath);
-            URLClassLoader urlC = new URLClassLoader(new URL[]{url},
-                    Thread.currentThread().getContextClassLoader());
-            loadAtmosphereDotXml(sc.getServletContext().
-                    getResourceAsStream(atmosphereDotXmlPath), urlC);
-
-            if (atmosphereHandlers.size() == 0) {
-                autoDetectAtmosphereHandlers(sc.getServletContext(), urlC);
-
-                if (atmosphereHandlers.size() == 0) {
-                    detectSupportedFramework(sc);
-                }
-            }
-
-            autoDetectWebSocketHandler(sc.getServletContext(), urlC);
-        } catch (Throwable t) {
-            throw new ServletException(t);
-        }
-    }
-
-    /**
-     * Auto-detect Jersey when no atmosphere.xml file are specified.
-     *
-     * @param sc {@link ServletConfig}
-     * @return true if Jersey classes are detected
-     * @throws ClassNotFoundException
-     */
-    protected boolean detectSupportedFramework(ServletConfig sc) throws ClassNotFoundException, IllegalAccessException,
-            InstantiationException, NoSuchMethodException, InvocationTargetException {
-
-        ClassLoader cl = Thread.currentThread().getContextClassLoader();
-        String broadcasterClassNameTmp = null;
-
-        try {
-            cl.loadClass(JERSEY_CONTAINER);
-
-            if (!isBroadcasterSpecified) {
-                broadcasterClassNameTmp = lookupDefaultBroadcasterType(JERSEY_BROADCASTER);
-
-                cl.loadClass(broadcasterClassNameTmp);
-            }
-            useStreamForFlushingComments = true;
-        } catch (Throwable t) {
-            logger.trace("", t);
-            return false;
-        }
-
-        logger.warn("Missing META-INF/atmosphere.xml but found the Jersey runtime. Starting Jersey");
-
-        // Jersey will handle itself the headers.
-        initParams.put(WRITE_HEADERS, "false");
-
-        ReflectorServletProcessor rsp = new ReflectorServletProcessor();
-        if (broadcasterClassNameTmp != null) broadcasterClassName = broadcasterClassNameTmp;
-        rsp.setServletClassName(JERSEY_CONTAINER);
-        sessionSupport(false);
-        initParams.put(DISABLE_ONSTATE_EVENT, "true");
-
-        String mapping = sc.getInitParameter(PROPERTY_SERVLET_MAPPING);
-        if (mapping == null) {
-            mapping = "/*";
-        }
-        Class<? extends Broadcaster> bc = (Class<? extends Broadcaster>) cl.loadClass(broadcasterClassName);
-
-
-        if (broadcasterFactory != null) {
-            broadcasterFactory.destroy();
-        }
-        broadcasterFactory = new DefaultBroadcasterFactory(bc, broadcasterLifeCyclePolicy, config);
-        BroadcasterFactory.setBroadcasterFactory(broadcasterFactory, config);
-
-        for (BroadcasterListener b : broadcasterListeners) {
-            broadcasterFactory.addBroadcasterListener(b);
-        }
-
-        Broadcaster b;
-
-        try {
-            b = broadcasterFactory.get(bc, mapping);
-        } catch (IllegalStateException ex) {
-            logger.warn("Two Broadcaster's named {}. Renaming the second one to {}", mapping, sc.getServletName() + mapping);
-            b = broadcasterFactory.get(bc, sc.getServletName() + mapping);
-        }
-
-        addAtmosphereHandler(mapping, rsp, b);
-        return true;
-    }
-
-    protected String lookupDefaultBroadcasterType(String defaultB) {
-        for (String b : broadcasterTypes) {
-            try {
-                Class.forName(b);
-                return b;
-            } catch (ClassNotFoundException e) {
-            }
-        }
-        return defaultB;
-    }
-
-    protected void sessionSupport(boolean sessionSupport) {
-        if (!isSessionSupportSpecified) {
-            config.setSupportSession(sessionSupport);
-        } else if (!config.isSupportSession()) {
-            // Don't turn off session support.  Once it's on, leave it on.
-            config.setSupportSession(sessionSupport);
-        }
-    }
-
-    /**
-     * Initialize {@link AtmosphereServletProcessor}
-     *
-     * @param sc the {@link ServletConfig}
-     * @throws javax.servlet.ServletException
-     */
-    public void initAtmosphereHandler(ServletConfig sc) throws ServletException {
-        AtmosphereHandler a;
-        AtmosphereHandlerWrapper w;
-        for (Entry<String, AtmosphereHandlerWrapper> h : atmosphereHandlers.entrySet()) {
-            w = h.getValue();
-            a = w.atmosphereHandler;
-            if (a instanceof AtmosphereServletProcessor) {
-                ((AtmosphereServletProcessor) a).init(sc);
-            }
-        }
-
-        if (atmosphereHandlers.size() == 0 && !SimpleHttpProtocol.class.isAssignableFrom(webSocketProtocol.getClass())) {
-            logger.debug("Adding a void AtmosphereHandler mapped to /* to allow WebSocket application only");
-            addAtmosphereHandler("/*", new AbstractReflectorAtmosphereHandler() {
-                @Override
-                public void onRequest(AtmosphereResource r) throws IOException {
-                    logger.debug("No AtmosphereHandler defined.");
-                }
-
-                @Override
-                public void destroy() {
-                }
-            });
-        }
-    }
-
-    protected void initWebSocket() {
-        if (webSocketProtocol == null) {
-            try {
-                webSocketProtocol = (WebSocketProtocol) Thread.currentThread().getContextClassLoader()
-                        .loadClass(webSocketProtocolClassName).newInstance();
-                logger.info("Installed WebSocketProtocol {} ", webSocketProtocolClassName);
-            } catch (Exception ex) {
-                try {
-                    webSocketProtocol = (WebSocketProtocol) AtmosphereFramework.class.getClassLoader()
-                            .loadClass(webSocketProtocolClassName).newInstance();
-                    logger.info("Installed WebSocketProtocol {} ", webSocketProtocolClassName);
-                } catch (Exception ex2) {
-                    logger.error("Cannot load the WebSocketProtocol {}", getWebSocketProtocolClassName(), ex);
-                    webSocketProtocol = new SimpleHttpProtocol();
-                }
-            }
-        }
-        webSocketProtocol.configure(config);
-    }
-
-    public AtmosphereFramework destroy() {
-        if (asyncSupport != null && AsynchronousProcessor.class.isAssignableFrom(asyncSupport.getClass())) {
-            ((AsynchronousProcessor) asyncSupport).shutdown();
-        }
-
-        // We just need one bc to shutdown the shared thread pool
-        for (Entry<String, AtmosphereHandlerWrapper> entry : atmosphereHandlers.entrySet()) {
-            AtmosphereHandlerWrapper handlerWrapper = entry.getValue();
-            handlerWrapper.atmosphereHandler.destroy();
-        }
-
-        BroadcasterFactory factory = broadcasterFactory;
-        if (factory != null) {
-            factory.destroy();
-            BroadcasterFactory.factory = null;
-        }
-        WebSocketProcessorFactory.getDefault().destroy();
-        return this;
-    }
-
-    /**
-     * Load AtmosphereHandler defined under META-INF/atmosphere.xml
-     *
-     * @param stream The input stream we read from.
-     * @param c      The classloader
-     */
-    protected void loadAtmosphereDotXml(InputStream stream, URLClassLoader c)
-            throws IOException, ServletException {
-
-        if (stream == null) {
-            return;
-        }
-
-        AtmosphereConfigReader.getInstance().parse(config, stream);
-        for (AtmosphereHandlerConfig atmoHandler : config.getAtmosphereHandlerConfig()) {
-            try {
-                AtmosphereHandler handler;
-
-                if (!ReflectorServletProcessor.class.getName().equals(atmoHandler.getClassName())) {
-                    handler = (AtmosphereHandler) c.loadClass(atmoHandler.getClassName()).newInstance();
-                } else {
-                    handler = new ReflectorServletProcessor();
-                }
-
-                logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", handler, atmoHandler.getContextRoot());
-
-                for (ApplicationConfiguration a : atmoHandler.getApplicationConfig()) {
-                    initParams.put(a.getParamName(), a.getParamValue());
-                }
-
-                for (FrameworkConfiguration a : atmoHandler.getFrameworkConfig()) {
-                    initParams.put(a.getParamName(), a.getParamValue());
-                }
-
-                for (AtmosphereHandlerProperty handlerProperty : atmoHandler.getProperties()) {
-
-                    if (handlerProperty.getValue() != null && handlerProperty.getValue().indexOf("jersey") != -1) {
-                        initParams.put(DISABLE_ONSTATE_EVENT, "true");
-                        useStreamForFlushingComments = true;
-                        broadcasterClassName = lookupDefaultBroadcasterType(JERSEY_BROADCASTER);
-                        broadcasterFactory = null;
-                        configureBroadcaster();
-                    }
-
-                    IntrospectionUtils.setProperty(handler, handlerProperty.getName(), handlerProperty.getValue());
-                    IntrospectionUtils.addProperty(handler, handlerProperty.getName(), handlerProperty.getValue());
-                }
-
-                sessionSupport(Boolean.valueOf(atmoHandler.getSupportSession()));
-
-                String broadcasterClass = atmoHandler.getBroadcaster();
-                Broadcaster b;
-                /**
-                 * If there is more than one AtmosphereHandler defined, their Broadcaster
-                 * may clash each other with the BroadcasterFactory. In that case we will use the
-                 * last one defined.
-                 */
-                if (broadcasterClass != null) {
-                    broadcasterClassName = broadcasterClass;
-                    ClassLoader cl = Thread.currentThread().getContextClassLoader();
-                    Class<? extends Broadcaster> bc = (Class<? extends Broadcaster>) cl.loadClass(broadcasterClassName);
-                    broadcasterFactory = new DefaultBroadcasterFactory(bc, broadcasterLifeCyclePolicy, config);
-                    BroadcasterFactory.setBroadcasterFactory(broadcasterFactory, config);
-                }
-
-                b = broadcasterFactory.lookup(atmoHandler.getContextRoot(), true);
-
-                AtmosphereHandlerWrapper wrapper = new AtmosphereHandlerWrapper(handler, b);
-                addMapping(atmoHandler.getContextRoot(), wrapper);
-
-                String bc = atmoHandler.getBroadcasterCache();
-                if (bc != null) {
-                    broadcasterCacheClassName = bc;
-                }
-
-                if (atmoHandler.getCometSupport() != null) {
-                    asyncSupport = (AsyncSupport) c.loadClass(atmoHandler.getCometSupport())
-                            .getDeclaredConstructor(new Class[]{AtmosphereConfig.class})
-                            .newInstance(new Object[]{config});
-                }
-
-                if (atmoHandler.getBroadcastFilterClasses() != null) {
-                    broadcasterFilters.addAll(atmoHandler.getBroadcastFilterClasses());
-                }
-
-                List<AtmosphereInterceptor> l = new ArrayList<AtmosphereInterceptor>();
-                if (atmoHandler.getAtmosphereInterceptorClasses() != null) {
-                    for (String a : atmoHandler.getAtmosphereInterceptorClasses()) {
-                        try {
-                            AtmosphereInterceptor ai = (AtmosphereInterceptor) c.loadClass(a).newInstance();
-                            ai.configure(config);
-                            l.add(ai);
-                        } catch (Throwable e) {
-                            logger.warn("", e);
-                        }
-                    }
-                }
-                wrapper.interceptors = l;
-                if (l.size() > 0) {
-                    logger.info("Installed AtmosphereInterceptor {} mapped to AtmosphereHandler {}", l, atmoHandler.getClassName());
-                }
-            } catch (Throwable t) {
-                logger.warn("Unable to load AtmosphereHandler class: " + atmoHandler.getClassName(), t);
-                throw new ServletException(t);
-            }
-
-        }
-    }
-
-    /**
-     * Set the {@link AsyncSupport} implementation. Make sure you don't set
-     * an implementation that only works on some Container. See {@link BlockingIOCometSupport}
-     * for an example.
-     *
-     * @param asyncSupport
-     */
-    public AtmosphereFramework setAsyncSupport(AsyncSupport asyncSupport) {
-        this.asyncSupport = asyncSupport;
-        return this;
-    }
-
-    /**
-     * @param asyncSupport
-     * @return
-     * @Deprecated - Use {@link #setAsyncSupport(AsyncSupport)}
-     */
-    public AtmosphereFramework setCometSupport(AsyncSupport asyncSupport) {
-        return setAsyncSupport(asyncSupport);
-    }
-
-    /**
-     * Return the current {@link AsyncSupport}
-     *
-     * @return the current {@link AsyncSupport}
-     */
-    public AsyncSupport getAsyncSupport() {
-        return asyncSupport;
-    }
-
-    /**
-     * Return the current {@link AsyncSupport}
-     *
-     * @return the current {@link AsyncSupport}
-     * @deprecated Use getAsyncSupport
-     */
-    public AsyncSupport getCometSupport() {
-        return asyncSupport;
-    }
-
-    /**
-     * Returns an instance of AsyncSupportResolver {@link AsyncSupportResolver}
-     *
-     * @return CometSupportResolver
-     */
-    protected AsyncSupportResolver createAsyncSupportResolver() {
-        return new DefaultAsyncSupportResolver(config);
-    }
-
-
-    /**
-     * Auto detect the underlying Servlet Container we are running on.
-     */
-    protected void autoDetectContainer() {
-        // Was defined in atmosphere.xml
-        if (getAsyncSupport() == null) {
-            setAsyncSupport(createAsyncSupportResolver()
-                    .resolve(useNativeImplementation, useBlockingImplementation, webSocketEnabled));
-        }
-
-        logger.info("Atmosphere is using async support: {} running under container: {}",
-                getAsyncSupport().getClass().getName(), asyncSupport.getContainerName());
-    }
-
-    /**
-     * Auto detect instance of {@link AtmosphereHandler} in case META-INF/atmosphere.xml
-     * is missing.
-     *
-     * @param servletContext {@link ServletContext}
-     * @param classloader    {@link URLClassLoader} to load the class.
-     * @throws java.net.MalformedURLException
-     * @throws java.net.URISyntaxException
-     */
-    public void autoDetectAtmosphereHandlers(ServletContext servletContext, URLClassLoader classloader)
-            throws MalformedURLException, URISyntaxException {
-
-        // If Handler has been added
-        if (atmosphereHandlers.size() > 0) return;
-
-        logger.info("Auto detecting atmosphere handlers {}", handlersPath);
-
-        String realPath = servletContext.getRealPath(handlersPath);
-
-        // Weblogic bug
-        if (realPath == null) {
-            URL u = servletContext.getResource(handlersPath);
-            if (u == null) return;
-            realPath = u.getPath();
-        }
-
-        loadAtmosphereHandlersFromPath(classloader, realPath);
-    }
-
-    public void loadAtmosphereHandlersFromPath(URLClassLoader classloader, String realPath) {
-        File file = new File(realPath);
-
-        if (file.isDirectory()) {
-            getFiles(file);
-            scanDone = true;
-
-            for (String className : possibleComponentsCandidate) {
-                try {
-                    className = className.replace('\\', '/');
-                    className = className.replaceFirst("^.*/(WEB-INF|target)(?:/scala-[^/]+)?/(test-)?classes/(.*)\\.class", "$3").replace("/", ".");
-                    Class<?> clazz = classloader.loadClass(className);
-
-                    if (AtmosphereHandler.class.isAssignableFrom(clazz)) {
-                        AtmosphereHandler handler = (AtmosphereHandler) clazz.newInstance();
-                        InjectorProvider.getInjector().inject(handler);
-                        addMapping("/" + handler.getClass().getSimpleName(),
-                                new AtmosphereHandlerWrapper(broadcasterFactory, handler, "/" + handler.getClass().getSimpleName()));
-                        logger.info("Installed AtmosphereHandler {} mapped to context-path: {}", handler, handler.getClass().getName());
-                    }
-                } catch (Throwable t) {
-                    logger.trace("failed to load class as an AtmosphereHandler: " + className, t);
-                }
-            }
-        }
-    }
-
-    /**
-     * Auto detect instance of {@link org.atmosphere.websocket.WebSocketHandler} in case META-INF/atmosphere.xml
-     * is missing.
-     *
-     * @param servletContext {@link ServletContext}
-     * @param classloader    {@link URLClassLoader} to load the class.
-     * @throws java.net.MalformedURLException
-     * @throws java.net.URISyntaxException
-     */
-    protected void autoDetectWebSocketHandler(ServletContext servletContext, URLClassLoader classloader)
-            throws MalformedURLException, URISyntaxException {
-
-        if (hasNewWebSocketProtocol) return;
-
-        logger.info("Auto detecting WebSocketHandler in {}", handlersPath);
-
-        String realPath = servletContext.getRealPath(handlersPath);
-
-        // Weblogic bug
-        if (realPath == null) {
-            URL u = servletContext.getResource(handlersPath);
-            if (u == null) return;
-            realPath = u.getPath();
-        }
-
-        loadWebSocketFromPath(classloader, realPath);
-    }
-
-    protected void loadWebSocketFromPath(URLClassLoader classloader, String realPath) {
-        File file = new File(realPath);
-
-        if (file.isDirectory()) {
-            getFiles(file);
-            scanDone = true;
-
-            for (String className : possibleComponentsCandidate) {
-                try {
-                    className = className.replace('\\', '/');
-                    className = className.replaceFirst("^.*/(WEB-INF|target)(?:/scala-[^/]+)?/(test-)?classes/(.*)\\.class", "$3").replace("/", ".");
-                    Class<?> clazz = classloader.loadClass(className);
-
-                    if (WebSocketProtocol.class.isAssignableFrom(clazz)) {
-                        webSocketProtocol = (WebSocketProtocol) clazz.newInstance();
-                        InjectorProvider.getInjector().inject(webSocketProtocol);
-                        logger.info("Installed WebSocketProtocol {}", webSocketProtocol);
-                    }
-                } catch (Throwable t) {
-                    logger.trace("failed to load class as an WebSocketProtocol: " + className, t);
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Get the list of possible candidate to load as {@link AtmosphereHandler}
-     *
-     * @param f the real path {@link File}
-     */
-    private void getFiles(File f) {
-        if (scanDone) return;
-
-        File[] files = f.listFiles();
-        for (File test : files) {
-            if (test.isDirectory()) {
-                getFiles(test);
-            } else {
-                String clazz = test.getAbsolutePath();
-                if (clazz.endsWith(".class")) {
-                    possibleComponentsCandidate.add(clazz);
-                }
-            }
-        }
-    }
-
-    /**
-     * Invoke the proprietary {@link AsyncSupport}
-     *
-     * @param req
-     * @param res
-     * @return an {@link Action}
-     * @throws IOException
-     * @throws ServletException
-     */
-    public Action doCometSupport(AtmosphereRequest req, AtmosphereResponse res) throws IOException, ServletException {
-        req.setAttribute(BROADCASTER_FACTORY, broadcasterFactory);
-        req.setAttribute(PROPERTY_USE_STREAM, useStreamForFlushingComments);
-        req.setAttribute(BROADCASTER_CLASS, broadcasterClassName);
-        req.setAttribute(ATMOSPHERE_CONFIG, config);
-
-        Action a = null;
-        try {
-            boolean skip = true;
-            String s = config.getInitParameter(ALLOW_QUERYSTRING_AS_REQUEST);
-            if (s != null) {
-                skip = Boolean.valueOf(s);
-            }
-            if (!skip || req.getAttribute(WEBSOCKET_SUSPEND) == null) {
-                Map<String, String> headers = configureQueryStringAsRequest(req);
-                String body = headers.remove(ATMOSPHERE_POST_BODY);
-                if (body != null && body.isEmpty()) {
-                    body = null;
-                }
-
-                req.headers(headers)
-                        .method(body != null && req.getMethod().equalsIgnoreCase("GET") ? "POST" : req.getMethod());
-
-                if (body != null) {
-                    req.body(body);
-                }
-            }
-
-            s = req.getHeader(X_ATMOSPHERE_TRACKING_ID);
-
-            // Lookup for websocket
-            if (s == null || s.equals("0")) {
-                String unique = config.getInitParameter(ApplicationConfig.UNIQUE_UUID_WEBSOCKET);
-                if (unique != null && Boolean.valueOf(unique)) {
-                    s = (String) req.getAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID);
-                }
-            }
-
-            if (s == null || s.equals("0")) {
-                s = UUID.randomUUID().toString();
-                res.setHeader(X_ATMOSPHERE_TRACKING_ID, s);
-            } else {
-                // This may breaks 1.0.0 application because the WebSocket's associated AtmosphereResource will
-                // all have the same UUID, and retrieving the original one for WebSocket, so we don't set it at all.
-                // Null means it is not an HTTP request.
-                if (req.resource() == null) {
-                    res.setHeader(X_ATMOSPHERE_TRACKING_ID, s);
-                } else if (req.getAttribute(WebSocket.WEBSOCKET_INITIATED) == null) {
-                    // WebSocket reconnect, in case an application manually set the header
-                    // (impossible to retrieve the headers normally with WebSocket or SSE)
-                    res.setHeader(X_ATMOSPHERE_TRACKING_ID, s);
-                }
-            }
-
-            if (req.getAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID) == null) {
-                req.setAttribute(SUSPENDED_ATMOSPHERE_RESOURCE_UUID, s);
-            }
-
-            a = asyncSupport.service(req, res);
-        } catch (IllegalStateException ex) {
-            if (ex.getMessage() != null && (ex.getMessage().startsWith("Tomcat failed") || ex.getMessage().startsWith("JBoss failed"))) {
-                if (!isFilter) {
-                    logger.warn("Failed using comet support: {}, error: {} Is the Nio or Apr Connector enabled?", asyncSupport.getClass().getName(),
-                            ex.getMessage());
-                }
-                logger.trace(ex.getMessage(), ex);
-
-                AsyncSupport current = asyncSupport;
-                asyncSupport = asyncSupport.supportWebSocket() ? new Tomcat7BIOSupportWithWebSocket(config) : new BlockingIOCometSupport(config);
-                if (current instanceof AsynchronousProcessor) {
-                    ((AsynchronousProcessor) current).shutdown();
-                }
-
-                asyncSupport.init(config.getServletConfig());
-                logger.warn("Using " + asyncSupport.getClass().getName());
-
-                a = asyncSupport.service(req, res);
-            } else {
-                logger.error("AtmosphereFramework exception", ex);
-                throw ex;
-            }
-        } finally {
-            if (a != null) {
-                notify(a.type(), req, res);
-            }
-
-            if (req != null && a != null && a.type() != Action.TYPE.SUSPEND) {
-                req.destroy();
-                res.destroy();
-                notify(Action.TYPE.DESTROYED, req, res);
-            }
-        }
-        return a;
-    }
-
-    /**
-     * Return the default {@link Broadcaster} class name.
-     *
-     * @return the broadcasterClassName
-     */
-    public String getDefaultBroadcasterClassName() {
-        return broadcasterClassName;
-    }
-
-    /**
-     * Set the default {@link Broadcaster} class name
-     *
-     * @param bccn the broadcasterClassName to set
-     */
-    public AtmosphereFramework setDefaultBroadcasterClassName(String bccn) {
-        broadcasterClassName = bccn;
-        return this;
-    }
-
-    /**
-     * <tt>true</tt> if Atmosphere uses {@link AtmosphereResponse#getOutputStream()}
-     * by default for write operation.
-     *
-     * @return the useStreamForFlushingComments
-     */
-    public boolean isUseStreamForFlushingComments() {
-        return useStreamForFlushingComments;
-    }
-
-    /**
-     * Set to <tt>true</tt> so Atmosphere uses {@link AtmosphereResponse#getOutputStream()}
-     * by default for write operation. Default is false.
-     *
-     * @param useStreamForFlushingComments the useStreamForFlushingComments to set
-     */
-    public AtmosphereFramework setUseStreamForFlushingComments(boolean useStreamForFlushingComments) {
-        this.useStreamForFlushingComments = useStreamForFlushingComments;
-        return this;
-    }
-
-    /**
-     * Get the {@link BroadcasterFactory} which is used by Atmosphere to construct
-     * {@link Broadcaster}
-     *
-     * @return {@link BroadcasterFactory}
-     */
-    public BroadcasterFactory getBroadcasterFactory() {
-        return broadcasterFactory;
-    }
-
-    /**
-     * Set the {@link BroadcasterFactory} which is used by Atmosphere to construct
-     * {@link Broadcaster}
-     *
-     * @return {@link BroadcasterFactory}
-     */
-    public AtmosphereFramework setBroadcasterFactory(final BroadcasterFactory broadcasterFactory) {
-        this.broadcasterFactory = broadcasterFactory;
-        configureBroadcaster();
-        return this;
-    }
-
-    /**
-     * Return the {@link org.atmosphere.cpr.BroadcasterCache} class name.
-     *
-     * @return the {@link org.atmosphere.cpr.BroadcasterCache} class name.
-     */
-    public String getBroadcasterCacheClassName() {
-        return broadcasterCacheClassName;
-    }
-
-    /**
-     * Set the {@link org.atmosphere.cpr.BroadcasterCache} class name.
-     *
-     * @param broadcasterCacheClassName
-     */
-    public void setBroadcasterCacheClassName(String broadcasterCacheClassName) {
-        this.broadcasterCacheClassName = broadcasterCacheClassName;
-        configureBroadcaster();
-    }
-
-    /**
-     * Add a new Broadcaster class name AtmosphereServlet can use when initializing requests, and when
-     * atmosphere.xml broadcaster element is unspecified.
-     *
-     * @param broadcasterTypeString
-     */
-    public AtmosphereFramework addBroadcasterType(String broadcasterTypeString) {
-        broadcasterTypes.add(broadcasterTypeString);
-        return this;
-    }
-
-    public String getWebSocketProtocolClassName() {
-        return webSocketProtocolClassName;
-    }
-
-    public AtmosphereFramework setWebSocketProtocolClassName(String webSocketProtocolClassName) {
-        hasNewWebSocketProtocol = true;
-        this.webSocketProtocolClassName = webSocketProtocolClassName;
-        return this;
-    }
-
-    public Map<String, AtmosphereHandlerWrapper> getAtmosphereHandlers() {
-        return atmosphereHandlers;
-    }
-
-    protected Map<String, String> configureQueryStringAsRequest(AtmosphereRequest request) {
-        Map<String, String> headers = new HashMap<String, String>();
-
-        Enumeration<String> e = request.getParameterNames();
-        String s;
-        while (e.hasMoreElements()) {
-            s = e.nextElement();
-            if (s.equalsIgnoreCase("Content-Type")) {
-                // Use the one set by the user first.
-                if (request.getContentType() == null ||
-                        !request.getContentType().equalsIgnoreCase(request.getParameter(s))) {
-                    request.contentType(request.getParameter(s));
-                }
-            }
-            headers.put(s, request.getParameter(s));
-        }
-        logger.trace("Query String translated to headers {}", headers);
-        return headers;
-    }
-
-    protected boolean isIECandidate(AtmosphereRequest request) {
-        String userAgent = request.getHeader("User-Agent");
-        if (userAgent == null) return false;
-
-        if (userAgent.contains("MSIE") || userAgent.contains(".NET")) {
-            // Now check the header
-            String transport = request.getHeader(HeaderConfig.X_ATMOSPHERE_TRANSPORT);
-            if (transport != null) {
-                return false;
-            } else {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    public WebSocketProtocol getWebSocketProtocol() {
-        // TODO: Spagetthi code, needs to rework.
-        // Make sure we initialized the WebSocketProtocol
-        initWebSocket();
-        return webSocketProtocol;
-    }
-
-    public boolean isUseNativeImplementation() {
-        return useNativeImplementation;
-    }
-
-    public AtmosphereFramework setUseNativeImplementation(boolean useNativeImplementation) {
-        this.useNativeImplementation = useNativeImplementation;
-        return this;
-    }
-
-    public boolean isUseBlockingImplementation() {
-        return useBlockingImplementation;
-    }
-
-    public AtmosphereFramework setUseBlockingImplementation(boolean useBlockingImplementation) {
-        this.useBlockingImplementation = useBlockingImplementation;
-        return this;
-    }
-
-    public String getAtmosphereDotXmlPath() {
-        return atmosphereDotXmlPath;
-    }
-
-    public AtmosphereFramework setAtmosphereDotXmlPath(String atmosphereDotXmlPath) {
-        this.atmosphereDotXmlPath = atmosphereDotXmlPath;
-        return this;
-    }
-
-    public String getHandlersPath() {
-        return handlersPath;
-    }
-
-    public AtmosphereFramework setHandlersPath(String handlersPath) {
-        this.handlersPath = handlersPath;
-        return this;
-    }
-
-    /**
-     * Return the location of the jars containing the application classes. Default is WEB-INF/lib
-     *
-     * @return the location of the jars containing the application classes. Default is WEB-INF/lib
-     */
-    public String getLibPath() {
-        return libPath;
-    }
-
-    /**
-     * Set the location of the jars containing the application.
-     *
-     * @param libPath the location of the jars containing the application.
-     * @return this
-     */
-    public AtmosphereFramework setLibPath(String libPath) {
-        this.libPath = libPath;
-        return this;
-    }
-
-    public String getWebSocketProcessorClassName() {
-        return webSocketProcessorClassName;
-    }
-
-    public AtmosphereFramework setWebsocketProcessorClassName(String webSocketProcessorClassName) {
-        this.webSocketProcessorClassName = webSocketProcessorClassName;
-        return this;
-    }
-
-    /**
-     * Add an {@link AtmosphereInterceptor} implementation. The adding order or {@link AtmosphereInterceptor} will be used, e.g
-     * the first added {@link AtmosphereInterceptor} will always be called first.
-     *
-     * @param c {@link AtmosphereInterceptor}
-     * @return this
-     */
-    public AtmosphereFramework interceptor(AtmosphereInterceptor c) {
-        boolean found = false;
-        for (AtmosphereInterceptor interceptor : interceptors) {
-            if (interceptor.getClass().equals(c.getClass())) {
-                found = true;
-                break;
-            }
-        }
-
-        if (!found) {
-            interceptors.addLast(c);
-            logger.info("Installed AtmosphereInterceptor {}. ", c);
-        }
-        return this;
-    }
-
-    /**
-     * Return the list of {@link AtmosphereInterceptor}
-     *
-     * @return the list of {@link AtmosphereInterceptor}
-     */
-    public LinkedList<AtmosphereInterceptor> interceptors() {
-        return interceptors;
-    }
-
-    /**
-     * Set the {@link AnnotationProcessor} class name.
-     *
-     * @param annotationProcessorClassName the {@link AnnotationProcessor} class name.
-     * @return this
-     */
-    public AtmosphereFramework annotationProcessorClassName(String annotationProcessorClassName) {
-        this.annotationProcessorClassName = annotationProcessorClassName;
-        return this;
-    }
-
-    /**
-     * Add an {@link AsyncSupportListener}
-     *
-     * @param asyncSupportListener an {@link AsyncSupportListener}
-     * @return this;
-     */
-    public AtmosphereFramework asyncSupportListener(AsyncSupportListener asyncSupportListener) {
-        asyncSupportListeners.add(asyncSupportListener);
-        return this;
-    }
-
-    /**
-     * Return the list of an {@link AsyncSupportListener}
-     *
-     * @return
-     */
-    public List<AsyncSupportListener> asyncSupportListeners() {
-        return asyncSupportListeners;
-    }
-
-    /**
-     * Add {@link BroadcasterListener} to all created {@link Broadcaster}
-     */
-    public AtmosphereFramework addBroadcasterListener(BroadcasterListener b) {
-        if (isInit) {
-            broadcasterFactory.addBroadcasterListener(b);
-        } else {
-            broadcasterListeners.add(b);
-        }
-        return this;
-    }
-
-    /**
-     * Return a configured instance of {@link AtmosphereConfig}
-     *
-     * @return a configured instance of {@link AtmosphereConfig}
-     */
-    public AtmosphereConfig getAtmosphereConfig() {
-        return config;
-    }
-
-    @Override
-    public ServletContext getServletContext() {
-        return servletConfig.getServletContext();
-    }
-
-    public ServletConfig getServletConfig() {
-        return servletConfig;
-    }
-
-    /**
-     * Return the list of {@link BroadcastFilter}
-     *
-     * @return the list of {@link BroadcastFilter
-     */
-    public List<String> broadcasterFilters() {
-        return broadcasterFilters;
-    }
-
-    /**
-     * Returns true if {@link java.util.concurrent.ExecutorService} shared amongst all components.
-     *
-     * @return true if {@link java.util.concurrent.ExecutorService} shared amongst all components.
-     */
-    public boolean isShareExecutorServices() {
-        return sharedThreadPools;
-    }
-
-    /**
-     * Set to true to have a {@link java.util.concurrent.ExecutorService} shared amongst all components.
-     *
-     * @param sharedThreadPools
-     * @return this
-     */
-    public AtmosphereFramework shareExecutorServices(boolean sharedThreadPools) {
-        this.sharedThreadPools = sharedThreadPools;
-        return this;
-    }
-
-    protected void autoConfigureService(ServletContext sc) throws IOException {
-        final ClassLoader cl = Thread.currentThread().getContextClassLoader();
-
-        String path = libPath != DEFAULT_LIB_PATH ? libPath : sc.getRealPath(handlersPath);
-        try {
-            AnnotationProcessor p = (AnnotationProcessor) cl.loadClass(annotationProcessorClassName).newInstance();
-            logger.info("Atmosphere is using {} for processing annotation", annotationProcessorClassName);
-
-            p.configure(this);
-            if (path != null) {
-                p.scan(new File(path));
-            }
-
-            String pathLibs = sc.getRealPath(DEFAULT_LIB_PATH);
-            if (pathLibs != null) {
-                File libFolder = new File(pathLibs);
-                File jars[] = libFolder.listFiles(new FilenameFilter() {
-
-                    @Override
-                    public boolean accept(File arg0, String arg1) {
-                        return arg1.endsWith(".jar");
-                    }
-                });
-
-                for (File file : jars) {
-                    p.scan(file);
-                }
-            }
-        } catch (Throwable e) {
-            logger.debug("Atmosphere's Service Annotation Not Supported. Please add https://github.com/rmuller/infomas-asl as dependencies or your own AnnotationProcessor to support @Service");
-            logger.trace("", e);
-            return;
-        }
-    }
-
-    protected void notify(Action.TYPE type, AtmosphereRequest request, AtmosphereResponse response) {
-        for (AsyncSupportListener l : asyncSupportListeners()) {
-            try {
-                switch (type) {
-                    case TIMEOUT:
-                        l.onTimeout(request, response);
-                        break;
-                    case CANCELLED:
-                        l.onClose(request, response);
-                        break;
-                    case SUSPEND:
-                        l.onSuspend(request, response);
-                        break;
-                    case RESUME:
-                        l.onSuspend(request, response);
-                        break;
-                    case DESTROYED:
-                        l.onDestroyed(request, response);
-                        break;
-                }
-            } catch (Throwable t) {
-                logger.warn("", t);
-            }
-        }
-    }
-}
\ No newline at end of file
index f8d8105286c19123f30fb4f54f32100cbe3829d4..cf1031dab2ee48239355bc65b32b876844223411 100644 (file)
@@ -65,11 +65,11 @@ public interface Constants {
             + " Widgetset version: %s\n"
             + "=================================================================";
 
-    static final String REQUIRED_ATMOSPHERE_VERSION = "1.0.12";
+    static final String REQUIRED_ATMOSPHERE_VERSION = "1.0.13";
 
     static final String INVALID_ATMOSPHERE_VERSION_WARNING = "\n"
             + "=================================================================\n"
-            + "Vaadin depends on Atomsphere {0} but version {1} was found.\n"
+            + "Vaadin depends on Atmosphere {0} but version {1} was found.\n"
             + "This might cause compatibility problems if push is used.\n"
             + "=================================================================";
 
index 2d63621c126b4d8c925631ab4d4089bfde2be7c9..f16cbb7390d8aa00d5803fb13d77bf04a655335e 100644 (file)
@@ -42,5 +42,5 @@ public class PushConstants implements Serializable {
      * The character used to mark message boundaries when messages may be split
      * into multiple fragments.
      */
-    public static final char MESSAGE_DELIMITER = '\0';
+    public static final char MESSAGE_DELIMITER = '|';
 }