Commit 762b2c95 authored by Tristan Cavelier's avatar Tristan Cavelier

erp5storage.js added

parent fbaf4ed9
/*
* Copyright 2013, Nexedi SA
* Released under the LGPL license.
* http://www.gnu.org/licenses/lgpl.html
*/
/*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
/*global jIO: true, $: true, btoa: true */
// JIO Erp5 Storage Description :
// {
// type: "erp5",
// url: {string}
// }
// {
// type: "erp5",
// url: {string},
// auth_type: {string}, (optional)
// - "auto" (default) (not implemented)
// - "basic"
// - "digest" (not implemented)
// realm: {string}, (optional)
// - undefined (default) (not implemented)
// - "<string>" realm name (not implemented)
// username: {string},
// password: {string} (optional)
// }
// {
// type: "erp5",
// url: {string},
// encoded_login: {string}
// }
// {
// type: "erp5",
// url: {string},
// secured_login: {string} (not implemented)
// }
jIO.addStorageType("erp5", function (spec, my) {
var priv = {}, that = my.basicStorage(spec, my), erp5 = {};
// ATTRIBUTES //
priv.url = null;
priv.encoded_login = null;
// CONSTRUCTOR //
/**
* Init the erp5 storage connector thanks to the description
* @method __init__
* @param {object} description The description object
*/
priv.__init__ = function (description) {
priv.url = description.url || "";
priv.url = priv.removeSlashIfLast(priv.url);
// if (description.secured_login) {
// not implemented
// } else
if (description.encoded_login) {
priv.encoded_login = description.encoded_login;
} else if (description.auth_type) {
if (description.auth_type === "basic") {
priv.encoded_login = "Basic " +
btoa((description.username || "") + ":" +
(description.password || ""));
}
} else {
priv.encoded_login = "";
}
};
// OVERRIDES //
that.specToStore = function () {
// TODO: secured password
// The encoded_login can be seen by anyone, we must find a way to secure it!
// secured_login = encrypt(encoded_login)
// encoded_login = decrypt(secured_login)
return {
"url": priv.url,
"encoded_login": priv.encoded_login
};
};
that.validateState = function () {
if (typeof priv.url !== "string" || priv.url === "") {
return "The erp5 server URL is not provided";
}
if (priv.encoded_login === null) {
return "Impossible to create the authorization";
}
return "";
};
// TOOLS //
/**
* Removes the last character if it is a "/". "/a/b/c/" become "/a/b/c"
* @method removeSlashIfLast
* @param {string} string The string to modify
* @return {string} The modified string
*/
priv.removeSlashIfLast = function (string) {
if (string[string.length - 1] === "/") {
return string.slice(0, -1);
}
return string;
};
/**
* Modify an ajax object to add default values
* @method makeAjaxObject
* @param {object} json The JSON object
* @param {string} method The erp5 request method
* @param {object} ajax_object The ajax object to override
* @return {object} A new ajax object with default values
*/
priv.makeAjaxObject = function (json, method, ajax_object) {
ajax_object.type = "POST";
ajax_object.dataType = "text";
ajax_object.data = JSON.stringify(json);
ajax_object.url = priv.url + "/JIO_" + method +
"?_=" + Date.now();
ajax_object.async = ajax_object.async === false ? false : true;
ajax_object.crossdomain = ajax_object.crossdomain === false ? false : true;
ajax_object.headers = ajax_object.headers || {};
if (ajax_object.headers.Authorization || priv.encoded_login) {
ajax_object.headers.Authorization = ajax_object.headers.Authorization ||
priv.encoded_login;
}
return ajax_object;
};
/**
* Runs all ajax requests for erp5Storage
* @method ajax
* @param {object} json The JSON object
* @param {string} method The erp5 request method
* @param {object} ajax_object The request parameters (optional)
*/
priv.ajax = function (json, method, ajax_object) {
return $.ajax(priv.makeAjaxObject(json, method, ajax_object || {}));
//.always(then || function () {});
};
/**
* Creates error objects for this storage
* @method createError
* @param {string} url url to clean up
* @return {object} error The error object
*/
priv.createError = function (status, message, reason) {
var error = {
"status": status,
"message": message,
"reason": reason
};
switch (status) {
case 404:
error.statusText = "Not found";
break;
case 405:
error.statusText = "Method Not Allowed";
break;
case 409:
error.statusText = "Conflicts";
break;
case 24:
error.statusText = "Corrupted Document";
break;
}
error.error = error.statusText.toLowerCase().split(" ").join("_");
return error;
};
/**
* Converts ajax error object to a JIO error object
* @method ajaxErrorToJioError
* @param {object} ajax_error_object The ajax error object
* @param {string} message The error message
* @param {string} reason The error reason
* @return {object} The JIO error object
*/
priv.ajaxErrorToJioError = function (ajax_error_object, message, reason) {
var jio_error_object = {};
jio_error_object.status = ajax_error_object.status;
jio_error_object.statusText = ajax_error_object.statusText;
jio_error_object.error =
ajax_error_object.statusText.toLowerCase().split(" ").join("_");
jio_error_object.message = message;
jio_error_object.reason = reason;
return jio_error_object;
};
/**
* Function that create an object containing jQuery like callbacks
* @method makeJQLikeCallback
* @return {object} jQuery like callback methods
*/
priv.makeJQLikeCallback = function () {
var result = null, emptyFun = function () {}, jql = {
"respond": function () {
result = arguments;
},
"to_return": {
"always": function (func) {
if (result) {
func.apply(func, result);
jql.to_return.always = emptyFun;
} else {
jql.respond = func;
}
return jql.to_return;
}
}
};
return jql;
};
// ERP5 REQUESTS //
/**
* Sends a request to ERP5
* @method erp5.genericRequest
* @param {object} doc The document object
* @param {string} method The ERP5 request method
* @param {boolean} parse Parse the data received if true
*/
erp5.genericRequest = function (json, method, parse) {
var jql = priv.makeJQLikeCallback(), error = null;
priv.ajax(json, method).always(function (one, state, three) {
if (state !== "success") {
error = priv.ajaxErrorToJioError(
one,
"An error occured on " + method,
"Unknown"
);
if (one.status === 404) {
error.reason = "Not Found";
}
return jql.respond(error, undefined);
}
if (parse) {
try {
one = JSON.parse(one);
} catch (e) {
return jql.respond(priv.createError(
24,
"Cannot parse data",
"Corrupted data"
), undefined);
}
}
if (typeof one.status === "number" && typeof one.error === "string") {
return jql.respond(one, undefined);
}
return jql.respond(undefined, one);
});
return jql.to_return;
};
// JIO COMMANDS //
/**
* The ERP5 storage generic command
* @method genericCommand
* @param {object} json The json to send
* @param {string} method The ERP5 request method
*/
priv.genericCommand = function (json, method) {
erp5.genericRequest(
json,
method,
method !== "getAttachment" // parse received data if not getAttachment
).always(function (err, response) {
if (err) {
return that.error(err);
}
return that.success(response);
});
};
/**
* Creates a new document
* @method post
* @param {object} command The JIO command
*/
that.post = function (command) {
priv.genericCommand(command.cloneDoc(), "post");
};
/**
* Creates or updates a document
* @method put
* @param {object} command The JIO command
*/
that.put = function (command) {
priv.genericCommand(command.cloneDoc(), "put");
};
/**
* Add an attachment to a document
* @method putAttachment
* @param {object} command The JIO command
*/
that.putAttachment = function (command) {
priv.genericCommand(command.cloneDoc(), "putAttachment");
};
/**
* Get a document
* @method get
* @param {object} command The JIO command
*/
that.get = function (command) {
priv.genericCommand(command.cloneDoc(), "get");
};
/**
* Get an attachment
* @method getAttachment
* @param {object} command The JIO command
*/
that.getAttachment = function (command) {
priv.genericCommand(command.cloneDoc(), "getAttachment");
};
/**
* Remove a document
* @method remove
* @param {object} command The JIO command
*/
that.remove = function (command) {
priv.genericCommand(command.cloneDoc(), "remove");
};
/**
* Remove an attachment
* @method removeAttachment
* @param {object} command The JIO command
*/
that.removeAttachment = function (command) {
priv.genericCommand(command.cloneDoc(), "removeAttachment");
};
/**
* Gets a document list from a distant erp5 storage
* Options:
* - {boolean} include_docs Also retrieve the actual document content.
* @method allDocs
* @param {object} command The JIO command
*/
that.allDocs = function (command) {
priv.genericCommand({
"query": command.getOption("query"),
"include_docs": command.getOption("include_docs")
}, "allDocs");
};
/**
* Checks a document state
* @method check
* @param {object} command The JIO command
*/
that.check = function (command) {
priv.genericCommand(command.cloneDoc(), "check");
};
/**
* Restore a document state to a coherent state
* @method repair
* @param {object} command The JIO command
*/
that.repair = function (command) {
priv.genericCommand(command.cloneDoc(), "repair");
};
priv.__init__(spec);
return that;
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment