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