]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/javascript/lib/js/opac/RemoteRequest.js
memory leak debugging, removed closures
[working/Evergreen.git] / Open-ILS / src / javascript / lib / js / opac / RemoteRequest.js
1 var XML_HTTP_GATEWAY = "gateway";
2 var XML_HTTP_SERVER = "gapines.org";
3 var XML_HTTP_MAX_TRIES = 3;
4
5 var _allrequests = new Array();
6
7 function cleanRemoteRequests() {
8         for( var i = 0; i!= _allrequests.length; i++ ) {
9                 var r = _allrequests[i];
10                 r.xmlhttp.onreadystatechange = function(){};
11                 r.xmlhttp                       = null;
12                 r.callback                      = null;
13                 r.userdata                      = null;
14                 _allrequests[i]         = null;
15         }
16 }
17
18 /* ----------------------------------------------------------------------- */
19 /* Request object */
20 function RemoteRequest( service, method ) {
21
22         _allrequests.push(this);
23
24         this.service    = service;
25         this.method             = method;
26         this.xmlhttp    = false;
27         this.name               = null;
28         this.sendCount = 0;
29
30         this.type               = "POST"; /* default */
31         this.id                 = service + method + Math.random();
32         this.cancelled = false;
33
34         var i = 2;
35         this.params = ""; 
36
37         while(i < arguments.length) {
38                 var object = js2JSON(arguments[i++]);
39                 this.params += "&param=" + encodeURIComponent(object);
40         }
41
42         if(!this.params) { this.params = ""; }
43         this.param_string = "service=" + service + "&method=" + method + this.params;
44
45         if( ! this.type || ! this.service || ! this.method ) {
46                 alert( "ERROR IN REQUEST PARAMS");
47                 return null;
48         }
49
50         if( this.buildXMLRequest() == null )
51                 alert("NEWER BROWSER");
52 }
53
54 /* constructs our XMLHTTPRequest object */
55 RemoteRequest.prototype.buildXMLRequest = function() {
56
57         try { 
58                 this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 
59         } catch (e) {
60                 try { 
61                         this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
62                 } catch (E) {
63                         this.xmlhttp = false;
64                 }
65         }
66
67         if (!this.xmlhttp && typeof XMLHttpRequest!='undefined') {
68                 this.xmlhttp = new XMLHttpRequest();
69         }
70
71         if(!this.xmlhttp) {
72                 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
73                 return null;
74         }
75
76         return true;
77 }
78
79
80 /* define the callback we use when this request has received
81         all of its data */
82 RemoteRequest.prototype.setCompleteCallback = function(callback) {
83
84         if(this.cancelled) return;
85         var object = this;
86         var xml = this.xmlhttp;
87
88         xml.onreadystatechange = function() {
89                 if( xml.readyState == 4 ) {
90
91                         try {
92                                 if(object.cancelled) return;
93                                 callback(object);
94
95                         } catch(E) {
96
97                                 /* if we receive a communication error, retry the request up
98                                         to XML_HTTP_MAX_TRIES attempts */
99                                 if( instanceOf(E, EXCommunication) ) {
100
101                                         if(object.sendCount >= XML_HTTP_MAX_TRIES ) {
102                                                 if(isXUL()) {
103                                                         throw object;
104                                                 } else {
105                                                         alert("Arrrgghh, Matey! Error communicating:\n" +
106                                                                  E  + "\n" + object.param_string);
107                                                 }
108                                         } else {
109                                                 object.buildXMLRequest();
110                                                 object.send();
111                                                 return;
112                                         }
113                                 } else { throw E; }
114                         } finally { object = null; }  
115                 }
116         }
117 }
118
119
120 /* http by default.  This makes it https. *ONLY works when
121         embedded in a XUL app. */
122 RemoteRequest.prototype.setSecure = function(bool) {
123         this.secure = bool; 
124 }
125
126 /** Send the request 
127   * By default, all calls are asynchronous.  if 'blocking' is
128   * set to true, then the call will block until a response
129   * is received.  If blocking, callbacks will not be called.
130   * In other words, you can assume the data is avaiable 
131   * (getResponseObject()) as soon as the send call returns. 
132   */
133 RemoteRequest.prototype.send = function(blocking) {
134
135         if(this.cancelled) return;
136
137         /* determine the xmlhttp server dynamically */
138         var url = location.protocol + "//" + location.host + "/" + XML_HTTP_GATEWAY;
139
140         if(isXUL()) {
141                 if(this.secure)
142                         url =   "https://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
143                 else
144                         url =   "http://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
145         }
146
147         var data = null;
148
149         if( this.type == 'GET' ) { 
150                 url +=  "?" + this.param_string; 
151         }
152
153         if(blocking) {
154                 this.xmlhttp.open(this.type, url, false);
155         } else {
156                 this.xmlhttp.open(this.type, url, true);
157         }
158
159
160         if( this.type == 'POST' ) {
161                 data = this.param_string;
162                 this.xmlhttp.setRequestHeader('Content-Type',
163                                 'application/x-www-form-urlencoded');
164         }
165
166         this.xmlhttp.send( data );
167         this.sendCount += 1;
168         return this;
169 }
170
171 /* returns the actual response text from the request */
172 RemoteRequest.prototype.getText = function() {
173         return this.xmlhttp.responseText;
174 }
175
176 RemoteRequest.prototype.isReady = function() {
177         return this.xmlhttp.readyState == 4;
178 }
179
180
181 /* returns the JSON->js result object  */
182 RemoteRequest.prototype.getResultObject = function() {
183         //this.callback = null;
184         if(this.cancelled) return null;
185
186         var text = this.xmlhttp.responseText;
187         var obj = JSON2js(text);
188
189         if(obj == null) {
190                 return null;
191         }
192
193         if(obj.is_err) { 
194                 throw new EXCommunication(obj.err_msg); 
195         }
196
197         if( obj[0] != null && obj[1] == null ) 
198                 obj = obj[0];
199
200         /* these are user level exceptions from the server code */
201         if(instanceOf(obj, ex)) {
202                 /* the opac will go ahead and spit out the error msg */
203                 if(!isXUL()) alert(obj.err_msg());
204                 throw obj;
205         }
206
207         if(instanceOf(obj, perm_ex)) {
208                 /* the opac will go ahead and spit out the error msg */
209                 if(!isXUL()) alert(obj.err_msg());
210                 throw obj;
211         }
212
213         return obj;
214 }
215
216 /* adds a new parameter to the request */
217 RemoteRequest.prototype.addParam = function(param) {
218         var string = encodeURIComponent(js2JSON(param));
219         this.param_string += "&param=" + string;
220 }
221