2 var XML_HTTP_GATEWAY = "gateway";
3 var XML_HTTP_SERVER = "gapines.org";
4 var XML_HTTP_MAX_TRIES = 3;
8 /* true if we've been absorbed by a XUL app */
19 /* ----------------------------------------------------------------------- */
22 /* keeping all requests in a global cache allows us to manage request
23 resends effectively */
25 /* Array of globally pending requests */
26 RemoteRequest.pending = new Array();
28 /* cleans requests (and null entries) from the pending array */
29 RemoteRequest.prunePending = function(id) {
30 var tmpArray = new Array();
31 for( var x in RemoteRequest.pending ) {
32 if( RemoteRequest.pending[x] != null ) {
33 var req = RemoteRequest.pending[x];
37 //debug("Cleaning " + req.id );
42 RemoteRequest.pending = tmpArray;
45 /* returns the number of pending requests */
46 RemoteRequest.numPending = function() {
47 return RemoteRequest.pending.length;
50 RemoteRequest.cancelAll = function() {
51 for( var x in RemoteRequest.pending ) {
52 if( RemoteRequest.pending[x] != null ) {
53 debug("Cancelling request...");
54 var req = RemoteRequest.pending[x];
62 /* ----------------------------------------------------------------------- */
63 /* Generic request manager */
64 function RequestBatch() {
65 this.requests = new Array();
67 RequestBatch.prototype.add = function(request) {
68 this.requests.push(request);
71 RequestBatch.prototype.remove = function(request) {
72 var newArray = new Array();
73 for( var i in this.requests ) {
74 if( this.requests[i] != null &&
75 this.requests[i].id != request.id )
76 newArray.push(this.requests[i]);
78 this.requests = newArray;
81 RequestBatch.prototype.pending = function() {
82 return this.requests.length;
85 /* cancels all requests in this batch that have not already been sent */
86 RequestBatch.prototype.cancel = function() {
87 for(var i in this.requests) {
88 if(this.requests[i] != null)
89 this.requests.cancelled = true;
93 /* ----------------------------------------------------------------------- */
95 function RemoteRequest( service, method ) {
97 this.service = service;
103 this.type = "POST"; /* default */
104 this.id = service + method + Math.random();
105 this.cancelled = false;
110 while(i < arguments.length) {
111 var object = js2JSON(arguments[i++]);
112 this.params += "¶m=" + encodeURIComponent(object);
113 debug("Remote Request adding param => " + object);
116 if(!this.params) { this.params = ""; }
117 this.param_string = "service=" + service + "&method=" + method + this.params;
119 if( ! this.type || ! this.service || ! this.method ) {
120 alert( "ERROR IN REQUEST PARAMS");
124 if( this.buildXMLRequest() == null )
125 alert("NEWER BROWSER");
128 RemoteRequest.prototype.clean = function() {
129 this.xmlhttp.onreadystatechange = function(){};
130 this.callback = null;
133 /* constructs our XMLHTTPRequest object */
134 RemoteRequest.prototype.buildXMLRequest = function() {
137 this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
140 this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
142 this.xmlhttp = false;
146 if (!this.xmlhttp && typeof XMLHttpRequest!='undefined') {
147 this.xmlhttp = new XMLHttpRequest();
151 alert("NEEDS NEWER JAVASCRIPT for XMLHTTPRequest()");
156 this.setCompleteCallback( this.callback );
162 /* define the callback we use when this request has received
164 RemoteRequest.prototype.setCompleteCallback = function(callback) {
166 if(this.cancelled) return;
169 var obj = this.xmlhttp;
170 this.callback = callback;
172 this.xmlhttp.onreadystatechange = function() {
173 if( obj.readyState == 4 ) {
176 if(object.cancelled) return;
181 debug("Processing Error in complete callback: [" + E + "]");
183 /* if we receive a communication error, retry the request up
184 to XML_HTTP_MAX_TRIES attempts */
185 if( instanceOf(E, EXCommunication) ) {
187 debug("Communication Error: [" + E + "]");
188 if(object.sendCount >= XML_HTTP_MAX_TRIES ) {
192 alert("Arrrgghh, Matey! Error communicating:\n" +
193 E + "\n" + object.param_string);
196 object.buildXMLRequest();
201 /* any other exception is alerted for now */
202 RemoteRequest.prunePending(object.id);
203 //alert("Exception: " + E);
208 /* on success, remove the request from the pending cache */
209 RemoteRequest.prunePending(object.id);
215 /* http by default. This makes it https. *ONLY works when
216 embedded in a XUL app. */
217 RemoteRequest.prototype.setSecure = function(bool) {
222 * By default, all calls are asynchronous. if 'blocking' is
223 * set to true, then the call will block until a response
224 * is received. If blocking, callbacks will not be called.
225 * In other words, you can assume the data is avaiable
226 * (getResponseObject()) as soon as the send call returns.
228 RemoteRequest.prototype.send = function(blocking) {
230 if(this.cancelled) return;
232 if( this.sendCount == 0)
233 RemoteRequest.pending.push(this);
235 debug("Resending request with id " + this.id
236 + " and send count " + this.sendCount);
238 /* determine the xmlhttp server dynamically */
239 var url = location.protocol + "//" + location.host + "/" + XML_HTTP_GATEWAY;
243 url = "https://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
245 //url = "http://" + XML_HTTP_SERVER + ":8080/" + XML_HTTP_GATEWAY;
246 url = "http://" + XML_HTTP_SERVER + "/" + XML_HTTP_GATEWAY;
251 if( this.type == 'GET' ) {
252 url += "?" + this.param_string;
256 this.xmlhttp.open(this.type, url, false);
258 this.xmlhttp.open(this.type, url, true);
262 if( this.type == 'POST' ) {
263 data = this.param_string;
264 this.xmlhttp.setRequestHeader('Content-Type',
265 'application/x-www-form-urlencoded');
268 //alert("Sending from " + location.href + " to " + url + " data [" + data + "]");
269 this.xmlhttp.send( data );
271 debug("Remote Request done sending");
275 /* returns the actual response text from the request */
276 RemoteRequest.prototype.getText = function() {
277 return this.xmlhttp.responseText;
280 RemoteRequest.prototype.isReady = function() {
281 return this.xmlhttp.readyState == 4;
285 /* returns the JSON->js result object */
286 RemoteRequest.prototype.getResultObject = function() {
287 if(this.cancelled) return null;
289 var text = this.xmlhttp.responseText;
290 var obj = JSON2js(text);
293 debug("received null response");
298 debug("Something's Wrong: " + js2JSON(obj));
299 throw new EXCommunication(obj.err_msg);
302 if( obj[0] != null && obj[1] == null )
305 /* these are user level exceptions from the server code */
306 if(instanceOf(obj, ex)) {
307 debug("Received user level exception: " + obj.err_msg());
308 /* the opac will go ahead and spit out the error msg */
309 if(!isXUL()) alert(obj.err_msg());
313 if(instanceOf(obj, perm_ex)) {
314 debug("Received permission error: " + obj.err_msg());
315 /* the opac will go ahead and spit out the error msg */
316 if(!isXUL()) alert(obj.err_msg());
323 /* adds a new parameter to the request */
324 RemoteRequest.prototype.addParam = function(param) {
325 var string = encodeURIComponent(js2JSON(param));
326 this.param_string += "¶m=" + string;