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