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