CLIENT GUI Framework
[vnfsdk/refrepo.git] / openo-portal / portal-common / src / main / webapp / common / thirdparty / cometd / cometd / ReloadExtension.js
1 /*\r
2  * Copyright (c) 2010 the original author or authors.\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 (function()\r
18 {\r
19     function bind(org_cometd)\r
20     {\r
21         if (!org_cometd.COOKIE)\r
22         {\r
23             org_cometd.COOKIE = {};\r
24             org_cometd.COOKIE.set = function(name, value, options)\r
25             {\r
26                 throw 'Abstract';\r
27             };\r
28             org_cometd.COOKIE.get = function(name)\r
29             {\r
30                 throw 'Abstract';\r
31             };\r
32         }\r
33 \r
34         /**\r
35          * The reload extension allows a page to be loaded (or reloaded)\r
36          * without having to re-handshake in the new (or reloaded) page,\r
37          * therefore resuming the existing cometd connection.\r
38          *\r
39          * When the reload() method is called, the state of the cometd\r
40          * connection and of the cometd subscriptions is stored in a cookie\r
41          * with a short max-age.\r
42          * The reload() method must therefore be called by page unload\r
43          * handlers, often provided by JavaScript toolkits.\r
44          *\r
45          * When the page is (re)loaded, this extension checks the cookie\r
46          * and restores the cometd connection and the cometd subscriptions.\r
47          */\r
48         return org_cometd.ReloadExtension = function(configuration)\r
49         {\r
50             var _cometd;\r
51             var _debug;\r
52             var _state = null;\r
53             var _cookieName = 'org.cometd.reload';\r
54             var _cookiePath = '/';\r
55             var _cookieMaxAge = 5;\r
56             var _batch = false;\r
57 \r
58             function _reload(config)\r
59             {\r
60                 if (_state && _state.handshakeResponse !== null)\r
61                 {\r
62                     _configure(config);\r
63                     _state.cookiePath = _cookiePath;\r
64                     var cookie = org_cometd.JSON.toJSON(_state);\r
65                     _debug('Reload extension saving cookie value', cookie);\r
66                     org_cometd.COOKIE.set(_cookieName, cookie, {\r
67                         'max-age': _cookieMaxAge,\r
68                         path: _cookiePath,\r
69                         expires: new Date(new Date().getTime() + _cookieMaxAge * 1000)\r
70                     });\r
71                 }\r
72             }\r
73 \r
74             function _similarState(oldState)\r
75             {\r
76                 // We want to check here that the CometD object\r
77                 // did not change much between reloads.\r
78                 // We just check the URL for now, but in future\r
79                 // further checks may involve the transport type\r
80                 // and other configuration parameters.\r
81                 return _state.url == oldState.url;\r
82             }\r
83 \r
84             function _configure(config)\r
85             {\r
86                 if (config)\r
87                 {\r
88                     if (typeof config.cookieMaxAge === 'number')\r
89                     {\r
90                         _cookieMaxAge = config.cookieMaxAge;\r
91                     }\r
92                     if (typeof config.cookieName === 'string')\r
93                     {\r
94                         _cookieName = config.cookieName;\r
95                     }\r
96                     if (typeof config.cookiePath === 'string')\r
97                     {\r
98                         _cookiePath = config.cookiePath;\r
99                     }\r
100                 }\r
101             }\r
102 \r
103             this.configure = _configure;\r
104 \r
105             this.registered = function(name, cometd)\r
106             {\r
107                 _cometd = cometd;\r
108                 _cometd.reload = _reload;\r
109                 _debug = _cometd._debug;\r
110             };\r
111 \r
112             this.unregistered = function()\r
113             {\r
114                 delete _cometd.reload;\r
115                 _cometd = null;\r
116             };\r
117 \r
118             this.outgoing = function(message)\r
119             {\r
120                 var channel = message.channel;\r
121 \r
122                 if (channel == '/meta/handshake')\r
123                 {\r
124                     _state = {};\r
125                     _state.url = _cometd.getURL();\r
126 \r
127                     var cookie = org_cometd.COOKIE.get(_cookieName);\r
128                     _debug('Reload extension found cookie value', cookie);\r
129                     // Is there a saved handshake response from a prior load ?\r
130                     if (cookie)\r
131                     {\r
132                         try\r
133                         {\r
134                             var oldState = org_cometd.JSON.fromJSON(cookie);\r
135 \r
136                             // Remove the cookie, not needed anymore\r
137                             org_cometd.COOKIE.set(_cookieName, '', {\r
138                                 'max-age': -1,\r
139                                 path: oldState.cookiePath,\r
140                                 expires: -1\r
141                             });\r
142 \r
143                             if (oldState.handshakeResponse && _similarState(oldState))\r
144                             {\r
145                                 _debug('Reload extension restoring state', oldState);\r
146                                 setTimeout(function()\r
147                                 {\r
148                                     _debug('Reload extension replaying handshake response', oldState.handshakeResponse);\r
149                                     _state.handshakeResponse = oldState.handshakeResponse;\r
150                                     _state.transportType = oldState.transportType;\r
151                                     _state.reloading = true;\r
152                                     var response = _cometd._mixin(true, {}, _state.handshakeResponse, {ext: {reload: true}});\r
153                                     response.supportedConnectionTypes = [_state.transportType];\r
154                                     _cometd.receive(response);\r
155                                     _debug('Reload extension replayed handshake response', response);\r
156                                 }, 0);\r
157 \r
158                                 // delay any sends until first connect is complete.\r
159                                 if (!_batch)\r
160                                 {\r
161                                     _batch = true;\r
162                                     _cometd.startBatch();\r
163                                 }\r
164                                 // This handshake is aborted, as we will replay the prior handshake response\r
165                                 return null;\r
166                             }\r
167                             else\r
168                             {\r
169                                 _debug('Reload extension could not restore state', oldState);\r
170                             }\r
171                         }\r
172                         catch(x)\r
173                         {\r
174                             _debug('Reload extension error while trying to restore cookie', x);\r
175                         }\r
176                     }\r
177                 }\r
178                 else if (channel == '/meta/connect')\r
179                 {\r
180                     if (!_state.transportType)\r
181                     {\r
182                         _state.transportType = message.connectionType;\r
183                         _debug('Reload extension tracked transport type', _state.transportType);\r
184                     }\r
185                 }\r
186                 return message;\r
187             };\r
188 \r
189             this.incoming = function(message)\r
190             {\r
191                 if (message.successful)\r
192                 {\r
193                     switch (message.channel)\r
194                     {\r
195                         case '/meta/handshake':\r
196                             // If the handshake response is already present, then we're replaying it.\r
197                             // Since the replay may have modified the handshake response, do not record it here.\r
198                             if (!_state.handshakeResponse)\r
199                             {\r
200                                 // Save successful handshake response\r
201                                 _state.handshakeResponse = message;\r
202                                 _debug('Reload extension tracked handshake response', message);\r
203                             }\r
204                             break;\r
205                         case '/meta/disconnect':\r
206                             _state = null;\r
207                             break;\r
208                         case '/meta/connect':\r
209                             if (_batch)\r
210                             {\r
211                                 _cometd.endBatch();\r
212                                 _batch = false;\r
213                             }\r
214                             break;\r
215                         default:\r
216                             break;\r
217                     }\r
218                 }\r
219                 return message;\r
220             };\r
221 \r
222             _configure(configuration);\r
223         };\r
224     }\r
225 \r
226     if (typeof define === 'function' && define.amd)\r
227     {\r
228         define(['org/cometd'], bind);\r
229     }\r
230     else\r
231     {\r
232         bind(org.cometd);\r
233     }\r
234 })();\r