+++ /dev/null
-/* -----------------------------------------------------------------------
- * Copyright (C) 2008 Georgia Public Library Service
- * Bill Erickson <erickson@esilibrary.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- * ----------------------------------------------------------------------- */
-
-/* session states */
-var OSRF_APP_SESSION_CONNECTED = 0;
-var OSRF_APP_SESSION_CONNECTING = 1;
-var OSRF_APP_SESSION_DISCONNECTED = 2;
-
-/* types of transport layers */
-var OSRF_TRANSPORT_TYPE_XHR = 1;
-var OSRF_TRANSPORT_TYPE_XMPP = 2;
-
-/* message types */
-var OSRF_MESSAGE_TYPE_REQUEST = 'REQUEST';
-var OSRF_MESSAGE_TYPE_STATUS = 'STATUS';
-var OSRF_MESSAGE_TYPE_RESULT = 'RESULT';
-var OSRF_MESSAGE_TYPE_CONNECT = 'CONNECT';
-var OSRF_MESSAGE_TYPE_DISCONNECT = 'DISCONNECT';
-
-/* message statuses */
-var OSRF_STATUS_CONTINUE = 100;
-var OSRF_STATUS_OK = 200;
-var OSRF_STATUS_ACCEPTED = 202;
-var OSRF_STATUS_COMPLETE = 205;
-var OSRF_STATUS_REDIRECTED = 307;
-var OSRF_STATUS_BADREQUEST = 400;
-var OSRF_STATUS_UNAUTHORIZED = 401;
-var OSRF_STATUS_FORBIDDEN = 403;
-var OSRF_STATUS_NOTFOUND = 404;
-var OSRF_STATUS_NOTALLOWED = 405;
-var OSRF_STATUS_TIMEOUT = 408;
-var OSRF_STATUS_EXPFAILED = 417;
-var OSRF_STATUS_INTERNALSERVERERROR = 500;
-var OSRF_STATUS_NOTIMPLEMENTED = 501;
-var OSRF_STATUS_VERSIONNOTSUPPORTED = 505;
-
-OpenSRF = {};
-OpenSRF.locale = null;
-
-/* makes cls a subclass of pcls */
-OpenSRF.set_subclass = function(cls, pcls) {
- var str = cls+'.prototype = new '+pcls+'();';
- str += cls+'.prototype.constructor = '+cls+';';
- str += cls+'.baseClass = '+pcls+'.prototype.constructor;';
- str += cls+'.prototype["super"] = '+pcls+'.prototype;';
- eval(str);
-}
-
-
-/* general session superclass */
-OpenSRF.Session = function() {
- this.remote_id = null;
- this.state = OSRF_APP_SESSION_DISCONNECTED;
-}
-
-OpenSRF.Session.transport = OSRF_TRANSPORT_TYPE_XHR; /* default to XHR */
-OpenSRF.Session.cache = {};
-OpenSRF.Session.find_session = function(thread_trace) {
- return OpenSRF.Session.cache[thread_trace];
-}
-OpenSRF.Session.prototype.cleanup = function() {
- delete OpenSRF.Session.cache[this.thread];
-}
-
-OpenSRF.Session.prototype.send = function(osrf_msg, args) {
- args = (args) ? args : {};
- switch(OpenSRF.Session.transport) {
- case OSRF_TRANSPORT_TYPE_XHR:
- return this.send_xhr(osrf_msg, args);
- case OSRF_TRANSPORT_TYPE_XMPP:
- return this.send_xmpp(osrf_msg, args);
- }
-}
-
-OpenSRF.Session.prototype.send_xhr = function(osrf_msg, args) {
- args.thread = this.thread;
- args.rcpt = this.remote_id;
- args.rcpt_service = this.service;
- new OpenSRF.XHRequest(osrf_msg, args).send();
-}
-
-OpenSRF.Session.prototype.send_xmpp = function(osrf_msg, args) {
- alert('xmpp transport not yet implemented');
-}
-
-
-/* client sessions make requests */
-OpenSRF.ClientSession = function(service) {
- this.service = service
- this.remote_id = null;
- this.locale = OpenSRF.locale || 'en-US';
- this.last_id = 0;
- this.thread = Math.random() + '' + new Date().getTime();
- this.requests = [];
- this.onconnect = null;
- OpenSRF.Session.cache[this.thread] = this;
-}
-OpenSRF.set_subclass('OpenSRF.ClientSession', 'OpenSRF.Session');
-
-
-OpenSRF.ClientSession.prototype.connect = function(args) {
- args = (args) ? args : {};
- this.remote_id = null;
-
- if(args.onconnect)
- this.onconnect = args.onconnect;
-
- /* if no handler is provided, make this a synchronous call */
- if(!this.onconnect)
- this.timeout = (args.timeout) ? args.timeout : 5;
-
- message = new osrfMessage({
- 'threadTrace' : this.reqid,
- 'type' : OSRF_MESSAGE_TYPE_CONNECT
- });
-
- this.send(message, {'timeout' : this.timeout});
-
- if(this.onconnect || this.state == OSRF_APP_SESSION_CONNECTED)
- return true;
- return false;
-}
-
-OpenSRF.ClientSession.prototype.disconnect = function(args) {
- this.send(
- new osrfMessage({
- 'threadTrace' : this.reqid,
- 'type' : OSRF_MESSAGE_TYPE_DISCONNECT
- })
- );
- this.remote_id = null;
-}
-
-
-OpenSRF.ClientSession.prototype.request = function(args) {
-
- if(this.state != OSRF_APP_SESSION_CONNECTED)
- this.remote_id = null;
-
- if(typeof args == 'string') {
- params = [];
- for(var i = 1; i < arguments.length; i++)
- params.push(arguments[i]);
-
- args = {
- method : args,
- params : params
- };
- } else {
- if(typeof args == 'undefined')
- args = {};
- }
-
- var req = new OpenSRF.Request(this, this.last_id++, args);
- this.requests.push(req);
- return req;
-}
-
-OpenSRF.ClientSession.prototype.find_request = function(reqid) {
- for(var i = 0; i < this.requests.length; i++) {
- var req = this.requests[i];
- if(req.reqid == reqid)
- return req;
- }
- return null;
-}
-
-OpenSRF.Request = function(session, reqid, args) {
- this.session = session;
- this.reqid = reqid;
-
- /* callbacks */
- this.onresponse = args.onresponse;
- this.oncomplete = args.oncomplete;
- this.onerror = args.onerror;
- this.onmethoderror = args.onmethoderror;
- this.ontransporterror = args.ontransporterror;
-
- this.method = args.method;
- this.params = args.params;
- this.timeout = args.timeout;
- this.response_queue = [];
- this.complete = false;
-}
-
-OpenSRF.Request.prototype.peek_last = function(timeout) {
- if(this.response_queue.length > 0) {
- var x = this.response_queue.pop();
- this.response_queue.push(x);
- return x;
- }
- return null;
-}
-
-OpenSRF.Request.prototype.peek = function(timeout) {
- if(this.response_queue.length > 0)
- return this.response_queue[0];
- return null;
-}
-
-OpenSRF.Request.prototype.recv = function(timeout) {
- if(this.response_queue.length > 0)
- return this.response_queue.shift();
- return null;
-}
-
-OpenSRF.Request.prototype.send = function() {
- method = new osrfMethod({'method':this.method, 'params':this.params});
- message = new osrfMessage({
- 'threadTrace' : this.reqid,
- 'type' : OSRF_MESSAGE_TYPE_REQUEST,
- 'payload' : method,
- 'locale' : this.session.locale
- });
-
- this.session.send(message, {
- 'timeout' : this.timeout,
- 'onresponse' : this.onresponse,
- 'oncomplete' : this.oncomplete,
- 'onerror' : this.onerror,
- 'onmethoderror' : this.onmethoderror,
- 'ontransporterror' : this.ontransporterror
- });
-}
-
-OpenSRF.NetMessage = function(to, from, thread, body) {
- this.to = to;
- this.from = from;
- this.thread = thread;
- this.body = body;
-}
-
-OpenSRF.Stack = function() {
-}
-
-// global inbound message queue
-OpenSRF.Stack.queue = [];
-
-OpenSRF.Stack.push = function(net_msg, callbacks) {
- var ses = OpenSRF.Session.find_session(net_msg.thread);
- if(!ses) return;
- ses.remote_id = net_msg.from;
- osrf_msgs = JSON2js(net_msg.body);
-
- // push the latest responses onto the end of the inbound message queue
- for(var i = 0; i < osrf_msgs.length; i++)
- OpenSRF.Stack.queue.push({msg : osrf_msgs[i], callbacks : callbacks, ses : ses});
-
- // continue processing responses, oldest to newest
- while(OpenSRF.Stack.queue.length) {
- var data = OpenSRF.Stack.queue.shift();
- OpenSRF.Stack.handle_message(data.ses, data.msg, data.callbacks);
- }
-}
-
-OpenSRF.Stack.handle_message = function(ses, osrf_msg, callbacks) {
-
- var req = null;
-
- if(osrf_msg.type() == OSRF_MESSAGE_TYPE_STATUS) {
-
- var payload = osrf_msg.payload();
- var status = payload.statusCode();
- var status_text = payload.status();
-
- if(status == OSRF_STATUS_COMPLETE) {
- req = ses.find_request(osrf_msg.threadTrace());
- if(req) {
- req.complete = true;
- if(callbacks.oncomplete && !req.oncomplete_called) {
- req.oncomplete_called = true;
- return callbacks.oncomplete(req);
- }
- }
- }
-
- if(status == OSRF_STATUS_OK) {
- ses.state = OSRF_APP_SESSION_CONNECTED;
-
- /* call the connect callback */
- if(ses.onconnect && !ses.onconnect_called) {
- ses.onconnect_called = true;
- return ses.onconnect();
- }
- }
-
- if(status == OSRF_STATUS_NOTFOUND || status == OSRF_STATUS_INTERNALSERVERERROR) {
- req = ses.find_request(osrf_msg.threadTrace());
- if(callbacks.onmethoderror)
- return callbacks.onmethoderror(req, status, status_text);
- }
- }
-
- if(osrf_msg.type() == OSRF_MESSAGE_TYPE_RESULT) {
- req = ses.find_request(osrf_msg.threadTrace());
- if(req) {
- req.response_queue.push(osrf_msg.payload());
- if(callbacks.onresponse)
- return callbacks.onresponse(req);
- }
- }
-}
-
-/* The following classes map directly to network-serializable opensrf objects */
-
-function osrfMessage(hash) {
- this.hash = hash;
- if(!this.hash.locale)
- this.hash.locale = OpenSRF.locale || 'en-US';
- this._encodehash = true;
-}
-osrfMessage.prototype.threadTrace = function(d) {
- if(arguments.length == 1)
- this.hash.threadTrace = d;
- return this.hash.threadTrace;
-}
-osrfMessage.prototype.type = function(d) {
- if(arguments.length == 1)
- this.hash.type = d;
- return this.hash.type;
-}
-osrfMessage.prototype.payload = function(d) {
- if(arguments.length == 1)
- this.hash.payload = d;
- return this.hash.payload;
-}
-osrfMessage.prototype.locale = function(d) {
- if(arguments.length == 1)
- this.hash.locale = d;
- return this.hash.locale;
-}
-osrfMessage.prototype.serialize = function() {
- return {
- "__c":"osrfMessage",
- "__p": {
- 'threadTrace' : this.hash.threadTrace,
- 'type' : this.hash.type,
- 'payload' : (this.hash.payload) ? this.hash.payload.serialize() : 'null',
- 'locale' : this.hash.locale
- }
- };
-}
-
-function osrfMethod(hash) {
- this.hash = hash;
- this._encodehash = true;
-}
-osrfMethod.prototype.method = function() {
- if(arguments.length == 1)
- this.hash.method = d;
- return this.hash.method;
-}
-osrfMethod.prototype.params = function() {
- if(arguments.length == 1)
- this.hash.params = d;
- return this.hash.params;
-}
-osrfMethod.prototype.serialize = function() {
- return {
- "__c":"osrfMethod",
- "__p": {
- 'method' : this.hash.method,
- 'params' : this.hash.params
- }
- };
-}
-
-function osrfMethodException(hash) {
- this.hash = hash;
- this._encodehash = true;
-}
-osrfMethodException.prototype.status = function() {
- if(arguments.length == 1)
- this.hash.status = d;
- return this.hash.status;
-}
-osrfMethodException.prototype.statusCode = function() {
- if(arguments.length == 1)
- this.hash.statusCode = d;
- return this.hash.statusCode;
-}
-function osrfConnectStatus(hash) {
- this.hash = hash;
- this._encodehash = true;
-}
-osrfConnectStatus.prototype.status = function() {
- if(arguments.length == 1)
- this.hash.status = d;
- return this.hash.status;
-}
-osrfConnectStatus.prototype.statusCode = function() {
- if(arguments.length == 1)
- this.hash.statusCode = d;
- return this.hash.statusCode;
-}
-function osrfResult(hash) {
- this.hash = hash;
- this._encodehash = true;
-}
-osrfResult.prototype.status = function() {
- if(arguments.length == 1)
- this.hash.status = d;
- return this.hash.status;
-}
-osrfResult.prototype.statusCode = function() {
- if(arguments.length == 1)
- this.hash.statusCode = d;
- return this.hash.statusCode;
-}
-osrfResult.prototype.content = function() {
- if(arguments.length == 1)
- this.hash.content = d;
- return this.hash.content;
-}
-function osrfServerError(hash) {
- this.hash = hash;
- this._encodehash = true;
-}
-osrfServerError.prototype.status = function() {
- if(arguments.length == 1)
- this.hash.status = d;
- return this.hash.status;
-}
-osrfServerError.prototype.statusCode = function() {
- if(arguments.length == 1)
- this.hash.statusCode = d;
- return this.hash.statusCode;
-}
-function osrfContinueStatus(hash) {
- this.hash = hash;
- this._encodehash = true;
-}
-osrfContinueStatus.prototype.status = function() {
- if(arguments.length == 1)
- this.hash.status = d;
- return this.hash.status;
-}
-osrfContinueStatus.prototype.statusCode = function() {
- if(arguments.length == 1)
- this.hash.statusCode = d;
- return this.hash.statusCode;
-}
-