hedera-web/js/vn/json-connection.js

316 lines
6.2 KiB
JavaScript

var Object = require ('./object');
var JsonException = require ('./json-exception');
/**
* Handler for JSON rest connections.
*/
module.exports = new Class
({
Extends: Object
,_connected: false
,_requestsCount: 0
,token: null
/**
* Initilizes the connection object.
*/
,initialize: function ()
{
this.parent ();
this.fetchToken ();
}
,fetchToken: function ()
{
var token = null;
if (sessionStorage.getItem ('vnToken'))
token = sessionStorage.getItem ('vnToken');
if (localStorage.getItem ('vnToken'))
token = localStorage.getItem ('vnToken');
this.token = token;
}
,clearToken: function ()
{
this.token = null;
localStorage.removeItem ('vnToken');
sessionStorage.removeItem ('vnToken');
}
/**
* Opens the connection to the REST service.
*
* @param {String} user The user name
* @param {String} password The user password
* @param {Boolean} remember Specifies if the user should be remembered
* @param {Function} openCallback The function to call when operation is done
*/
,open: function (user, pass, remember, callback)
{
if (user !== null && user !== undefined)
{
var params = {
'user': user
,'password': pass
,'remember': remember
};
}
else
var params = null;
this.send ('core/login', params,
this._onOpen.bind (this, callback, remember));
}
/*
* Called when open operation is done.
*/
,_onOpen: function (callback, remember, json, error)
{
if (json && json.login)
{
this._connected = true;
this.token = json.token;
var storage = remember ? localStorage : sessionStorage;
storage.setItem ('vnToken', this.token);
this.signalEmit ('openned');
}
else
this._closeClient ();
if (callback)
callback (this, this._connected, error);
}
/**
* Closes the connection to the REST service.
*
* @param {Function} callback The function to call when operation is done
*/
,close: function (callback)
{
this._closeClient ();
this.send ('core/logout', null,
this._onClose.bind (this, callback));
}
/*
* Called when close operation is done.
*/
,_onClose: function (callback, json, error)
{
this.signalEmit ('closed');
if (callback)
callback (this, json === true, error);
}
,_closeClient: function ()
{
this._connected = false;
this.clearToken ();
}
/**
* Suppants another user.
*
* @param {String} user The user name
* @param {Function} callback The callback function
*/
,supplantUser: function (user, callback)
{
var params = {'supplantUser': user};
this.send ('core/supplant', params,
this._onUserSupplant.bind (this, callback));
}
,_onUserSupplant: function (callback, json, error)
{
if (json)
this.token = json;
if (callback)
callback (json != null);
}
/**
* Ends the user supplanting and restores the last login.
*/
,supplantEnd: function ()
{
this.fetchToken ();
}
/**
* Executes the specified REST service with the given params and calls
* the callback when response is received.
*
* @param {String} restService The service path
* @param {Map} params The params to pass to the service
* @param {Function} callback The response callback
*/
,send: function (restService, params, callback)
{
if (!params)
params = {};
params['srv'] = 'json:'+ restService;
this.sendWithUrl (params, callback, 'POST', '.');
}
,sendForm: function (form, callback)
{
var params = {};
var elements = form.elements;
for (var i = 0; i < elements.length; i++)
if (elements[i].name)
params[elements[i].name] = elements[i].value;
this.sendWithUrl (params, callback, 'POST', form.action);
}
,sendFormMultipart: function (form, callback)
{
var formData = new FormData (form);
if (this.token)
formData.append ('token', this.token);
var request = new XMLHttpRequest ();
request.open ('POST', form.action, true);
request.onreadystatechange =
this._onStateChange.bind (this, request, callback);
request.send (formData);
this._addRequest ();
}
/*
* Called when REST response is received.
*/
,sendWithUrl: function (params, callback, method, url)
{
if (this.token)
params['token'] = this.token;
var request = new XMLHttpRequest ();
request.open (method, url, true);
request.setRequestHeader ('Content-Type',
'application/x-www-form-urlencoded');
request.onreadystatechange =
this._onStateChange.bind (this, request, callback);
request.send (Vn.Url.makeUri (params));
this._addRequest ();
}
,_addRequest: function ()
{
this._requestsCount++;
if (this._requestsCount === 1)
this.signalEmit ('loading-changed', true);
}
,_onStateChange: function (request, callback)
{
if (request.readyState !== 4)
return;
this._requestsCount--;
if (this._requestsCount === 0)
this.signalEmit ('loading-changed', false);
var data = null;
var error = null;
try {
if (request.status == 0)
{
var ex = new JsonException ();
ex.message = _('The server does not respond, please check your Internet connection');
throw ex;
}
var contentType = null;
try {
contentType = request
.getResponseHeader ('Content-Type')
.split (';')[0]
.trim ();
}
catch (e) {}
if (contentType != 'application/json')
{
var ex = new JsonException ();
ex.message = request.statusText;
ex.code = request.status;
throw ex;
}
var json = JSON.parse (request.responseText);
var jsData = json.data;
//var jsWarns = json.warnings;
if (request.status == 200)
{
data = jsData;
}
else
{
var exception = jsData.exception;
if (exception)
exception = exception
.replace (/\\/g, '.')
.replace (/Exception$/, '')
.replace (/^Vn\.Web\./, '');
var ex = new JsonException ();
ex.exception = exception;
ex.message = jsData.message;
ex.code = jsData.code;
ex.file = jsData.file;
ex.line = jsData.line;
ex.trace = jsData.trace;
throw ex;
}
}
catch (e)
{
data = null;
error = e;
}
if (callback)
try {
callback (data, error);
error = null;
}
catch (e)
{
error = e;
}
if (error)
{
if (error.exception == 'SessionExpired')
this.clearToken ();
this.signalEmit ('error', error);
}
}
});