source: branches/1.2/workflow/js/nano/NanoAjax.class.js @ 1349

Revision 1349, 9.9 KB checked in by niltonneto, 15 years ago (diff)

Ticket #561 - Inclusão do módulo Workflow faltante nessa versão.

  • Property svn:executable set to *
Line 
1
2// -----------------------------------------------------------------------------
3// CLASS NanoAjax
4function NanoAjax()
5{
6    /* Instance Variables */
7
8    // +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
9    // Public variables
10
11    this.asynchronousMode  = true;
12    this.requestMethod     = 'POST';
13    this.ajaxServerUrl     = '';
14
15    this.statusTranslation = [ 'initializing...',
16                               'connecting...',
17                               'connection established',
18                               'receiving data...',
19                               'done.',
20                               'decoding received data...',
21                               'processing data...',
22                               'done (processing)!' ];
23
24    this.onStateChangeId   = null;
25
26    this.errorReporting    = true;
27    this.disableExceptionReporting = false;
28
29    // only needed if request method is set to: GET
30    this.preparedGetData   = '';
31
32    // -------------------------------------------------------------------------
33    // Private variables
34
35    var _this              = this;
36    var _xmlHttpRequest    = null;
37
38    var _virtualRequest    = new Object();
39
40    var _responseHeader    = '';
41    var _responseBody      = '';
42
43
44        // #########################################################################
45    // Privileged Method (has public access and can access private vars & funcs)
46
47    // event handler
48    this.onStateChange     = null;
49    this.onSuccess         = null;
50    this.onError           = null;
51    this.onException       = null;
52
53    // public accessable methods
54    this.addVirtualRequest   = _addVirtualRequest;
55    this.isVirtualRequestSet = _isVirtualRequestSet;
56    this.sendRequest         = _executeRequest;
57
58
59    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
60        // PRIVATE Methods
61
62    /**
63     * checks if virtual request is set
64     *
65     * @access private
66     */
67        function _isVirtualRequestSet()
68        {
69        for ( virtualRequest in _virtualRequest )
70        {
71            return true;
72        }
73
74        return false;
75        }
76
77
78    /**
79     * executes real AJAX request
80     *
81     * @access private
82     */
83    function _executeRequest()
84    {
85        _initializeXmlHttpRequest();
86
87        if( typeof _xmlHttpRequest == 'object' )
88        {
89            this.requestMethod =  this.requestMethod.toUpperCase();
90
91                _xmlHttpRequest.open( this.requestMethod,      // POST or GET
92                                      this.ajaxServerUrl +     // full url to Ajax server
93                                      this.preparedGetData,    // with GET parameterdata
94                                      this.asynchronousMode ); // true = async
95
96                if( this.requestMethod == 'POST' )
97                {
98                // set various header parameter
99                _setPostRequestHeader();
100                }
101
102            // set function if state changes (handler)
103                _xmlHttpRequest.onreadystatechange = _readyStateHandler;
104
105            // now realy send (execute) request to NanoAjax server (with JSON string)
106                _xmlHttpRequest.send( JSON.stringify(_virtualRequest) );
107
108                // release object preventing memory leaks
109                delete _xmlHttpRequest;
110        }
111        else
112        {
113            alert('ERROR while creating xmlhttprequest object!!!\n\n'+
114                  'Your System is not able to create a xmlhttprequest object!');
115        }
116    }
117
118
119    /**
120     * ready state handler (called every time state changes)
121     *
122     * @access private
123     */
124    function _readyStateHandler()
125    {
126        if( _this.onStateChange )
127        {
128            _this.onStateChange( _xmlHttpRequest.readyState,
129                                 _this.statusTranslation[_xmlHttpRequest.readyState],
130                                 _this.onStateChangeId );
131        }
132
133        try
134        {
135            if ( // request finished
136                 _xmlHttpRequest.readyState == 4
137                 && // HTTP: OK                      HTTP: not modified
138                 ( _xmlHttpRequest.status == 200 || _xmlHttpRequest.status == 304 )
139               )
140            {
141                _responseHeader = _xmlHttpRequest.getAllResponseHeaders();
142                _responseBody   = _xmlHttpRequest.responseText;
143
144                if( -1 == _checkPhpError( _responseBody ) )
145                {
146                    if( _this.onSuccess )
147                    {
148                        var _json_decoded = _getJsonDecodedResponse(_responseBody);
149
150                        if( true == (exception_response = _checkServerException(_json_decoded)) )
151                        {
152                            _this.onSuccess( _json_decoded );
153                        }
154                        else
155                        {
156                            ( _this.onException )
157                                  ? _this.onException( _responseHeader,
158                                                       _responseBody,
159                                                       exception_response )
160
161                                  : _defaultErrorHandler( 'SERVER-SIDE EXCEPTION',
162                                                          exception_response );
163                        }
164                    }
165                    else
166                    {
167                        alert( 'No \'onSuccess\' handler defined!!!\n\n'+_responseBody );
168                    }
169                }
170                else
171                {
172                    ( _this.onError )
173                        ? _this.onError( _responseBody )
174                        : _defaultErrorHandler( 'SERVER-SIDE ERROR',
175                                                'Request could NOT finished!!!' );
176                }
177
178                _clearVirtualRequestData();
179            }
180        }
181        catch( exception )
182        {
183            _clearVirtualRequestData();
184
185            ( _this.onError )
186                ? _this.onError( exception )
187                : _defaultErrorHandler( 'EXCEPTION', exception );
188        }
189    }
190
191
192    /**
193     * initializing xmlhttprequest object by iterate over all given methods,
194     * to find correct browser implementation.
195     *
196     * @access private
197     */
198    function _initializeXmlHttpRequest()
199    {
200        if( _xmlHttpRequest == undefined || _xmlHttpRequest == null )
201        {
202            _xmlHttpRequest = Try.these
203            (
204                function() { return new ActiveXObject('Msxml2.XMLHTTP')   },
205                function() { return new ActiveXObject('Microsoft.XMLHTTP')},
206                function() { return new XMLHttpRequest()                  }
207            ) || false;
208        }
209    }
210
211
212    /**
213     * sets POST request header
214     *
215     * @access private
216     */
217    function _setPostRequestHeader()
218    {
219        // set method, url and protocol / version
220        _xmlHttpRequest.setRequestHeader( 'Method',
221                                          this.requestMethod + ' ' +
222                                          this.ajaxServerUrl + ' HTTP/1.1' );
223
224        // set content type for POST data
225        _xmlHttpRequest.setRequestHeader( 'Content-Type',
226                                          'application/x-www-form-urlencoded' );
227
228        // close connection after transfer
229        _xmlHttpRequest.setRequestHeader( 'Connection' , 'close' );
230    }
231
232
233    /**
234     * add a virtual request to request container (an object)
235     *
236     * @access private
237     */
238    function _addVirtualRequest( requestIdentifier, requestObject )
239    {
240        if( null != requestObject && undefined != requestObject )
241        {
242            _virtualRequest[requestIdentifier] = requestObject;
243        }
244    }
245
246
247    /**
248     * checks for server side PHP errors
249     *
250     * @access private
251     */
252    function _checkPhpError( response_string )
253    {
254        return (response_string.toLowerCase()).search(/((parse|fatal) error)|(fatal|warning|notice)/);
255    }
256
257
258    /**
259     * checks for server side PHP exceptions
260     *
261     * @access private
262     */
263    function _checkServerException( decoded_json_data )
264    {
265        var request_exception = new Array();
266
267        for( var requestIdentifier in decoded_json_data)
268        {
269            if( decoded_json_data[requestIdentifier]['exception'] )
270            {
271                request_exception.push('Exception happend in (virtual) request : '+
272                                       requestIdentifier+' {request identifier}\n'+
273                                       decoded_json_data[requestIdentifier]['exception'] );
274            }
275        }
276
277        return (request_exception.length > 0 )
278                   ? request_exception.join('\n')
279                   : true;
280    }
281
282
283    /**
284     * default error handler (if none is specified)
285     *
286     * @access private
287     */
288    function _defaultErrorHandler( type_header, message )
289    {
290        if( true == this.errorReporting )
291        {
292            alert( 'NanoAjax Class: '+type_header+' !!!\n'+
293                   ('=').repeat(54)+  '\n'+
294                   '\n'+message +   '\n\n'+
295                   ('=').repeat(54)+'\n\n'+
296                   'Response Header:   \n'+
297                   ('-').repeat(100)+ '\n'+
298                   _responseHeader +  '\n'+
299                   'Response Body:     \n'+
300                   ('-').repeat(100)+ '\n'+
301                   _responseBody );
302        }
303    }
304
305
306    /**
307     *
308     *
309     * @access private
310     */
311    function _getJsonDecodedResponse( response )
312    {
313        if( _this.onStateChange )
314        {
315            _this.onStateChange( 5,
316                                 ((_this.statusTranslation) ? _this.statusTranslation[5] : 5),
317                                 _this.onStateChangeId );
318        }
319        return JSON.parse(response);
320    }
321
322
323    function _clearVirtualRequestData()
324    {
325        _virtualRequest = new Object();
326    }
327
328    /**
329     * debugging, triggers AJAX requests / responses into div container
330     *
331     * @access private
332     */
333    function _triggerAjaxData( data )
334    {
335        if( $('id_AJAX_data') )
336        {
337            $('id_AJAX_data').innerHTML = data + $('id_AJAX_data').innerHTML;
338        }
339    }
340}
Note: See TracBrowser for help on using the repository browser.