Commit 802a22f7 authored by Tristan Cavelier's avatar Tristan Cavelier Committed by Sebastien Robin

jio.js modified in order to extends this API. And More!

parent fe5e889f
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<title>JIO</title> <title>JIO</title>
<script type="text/javascript" src="js/jquery/jquery.js"></script> <script type="text/javascript" src="js/jquery/jquery.js"></script>
<script type="text/javascript" src="unhosted/jio.js"></script>
<script type="text/javascript" src="unhosted/base64.js"></script> <script type="text/javascript" src="unhosted/base64.js"></script>
<script type="text/javascript" src="unhosted/sjcl.js"></script> <script type="text/javascript" src="unhosted/sjcl.js"></script>
<script type="text/javascript" src="unhosted/jio.js"></script> <script type="text/javascript" src="unhosted/jio.storage.js"></script>
</head> </head>
<body> <body>
<div id="divbody"> <div id="divbody">
...@@ -33,62 +34,71 @@ var is_array = function (v) { ...@@ -33,62 +34,71 @@ var is_array = function (v) {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Preparing JIO // Preparing JIO
//// Setting events reactions //// Setting events reactions
JIO.subscribe('start_saving', function (o) { JIO.subscribe('job_done', function (job) {
$('#divdebug').html($('#divdebug').html() + '<br/>' +
job.method + ': "' + job.fileName + '" OK!');
switch(job.method) {
case 'load':
objectDump(job);
$('#divdebug').html($('#divdebug').html() +
' Content : "' + job.file.content + '"');
break;
}
});
JIO.subscribe('job_fail', function (job) {
$('#diverror').html($('#diverror').html() + '<br/>' +
job.method + ': "' + job.fileName + '" FAILED! ' + job.message);
});
JIO.subscribe('start_saving', function () {
console.log ('start_saving received'); console.log ('start_saving received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' + $('#divmessage').html($('#divmessage').html() + '<br/>' +
'Saving ...'); 'Saving ...');
// $('#divdebug').html($('#divdebug').html() + '<br/>' + // $('#divdebug').html($('#divdebug').html() + '<br/>' +
// 'save remainingjobs: ' + o.remaining.save); // 'save remainingjobs: ' + o.remaining.save);
}); });
JIO.subscribe('stop_saving', function (o) { JIO.subscribe('stop_saving', function () {
console.log ('stop_saving received'); console.log ('stop_saving received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' + $('#divmessage').html($('#divmessage').html() + '<br/>' +
'Saving ended.'); 'Saving ended.');
}); });
JIO.subscribe('start_loading', function (e,o,r) { JIO.subscribe('start_loading', function () {
console.log ('start_loading received'); console.log ('start_loading received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' + $('#divmessage').html($('#divmessage').html() + '<br/>' +
'Loading "' + o.fileName + '"...'); 'Loading ...');
$('#divdebug').html($('#divdebug').html() + '<br/>' +
'load remainingjobs: ' + r);
}); });
JIO.subscribe('stop_loading', function (e,o) { JIO.subscribe('stop_loading', function () {
console.log ('stop_loading received'); console.log ('stop_loading received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' +
'Loading ended with result: ' + o.status + ', message: ' + o.message);
});
JIO.subscribe('start_deleting', function (e,o,r) {
console.log ('start_deleting received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' + $('#divmessage').html($('#divmessage').html() + '<br/>' +
'Deleting "' + o.fileName + '"...'); 'Loading ended.');
$('#divdebug').html($('#divdebug').html() + '<br/>' +
'delete remainingjobs: ' + r);
});
JIO.subscribe('stop_deleting', function (e,o) {
console.log ('stop_deleting received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' +
'Deleting ended with result: ' + o.status + ', message: ' + o.message);
});
JIO.subscribe('start_gettinglist', function (e,o) {
console.log ('start_deleting received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' +
'Getting list...');
});
JIO.subscribe('stop_gettinglist', function (e,o) {
console.log ('stop_deleting received');
objectDump(o);
$('#divmessage').html($('#divmessage').html() + '<br/>' +
'Getting list ended with result: ' + o.status + ', message: ' + o.message);
$('#divdebug').html($('#divdebug').html() + '<br/>' +
'getList: ' + JSON.stringify(o.list));
}); });
// JIO.subscribe('start_deleting', function (e,o,r) {
// console.log ('start_deleting received');
// objectDump(o);
// $('#divmessage').html($('#divmessage').html() + '<br/>' +
// 'Deleting "' + o.fileName + '"...');
// $('#divdebug').html($('#divdebug').html() + '<br/>' +
// 'delete remainingjobs: ' + r);
// });
// JIO.subscribe('stop_deleting', function (e,o) {
// console.log ('stop_deleting received');
// objectDump(o);
// $('#divmessage').html($('#divmessage').html() + '<br/>' +
// 'Deleting ended with result: ' + o.status + ', message: ' + o.message);
// });
// JIO.subscribe('start_gettinglist', function (e,o) {
// console.log ('start_deleting received');
// objectDump(o);
// $('#divmessage').html($('#divmessage').html() + '<br/>' +
// 'Getting list...');
// });
// JIO.subscribe('stop_gettinglist', function (e,o) {
// console.log ('stop_deleting received');
// objectDump(o);
// $('#divmessage').html($('#divmessage').html() + '<br/>' +
// 'Getting list ended with result: ' + o.status + ', message: ' + o.message);
// $('#divdebug').html($('#divdebug').html() + '<br/>' +
// 'getList: ' + JSON.stringify(o.list));
// });
//// events set //// events set
//// init JIO //// init JIO
...@@ -97,10 +107,10 @@ if ( !JIO.isReady() ) alert('Not ready'); ...@@ -97,10 +107,10 @@ if ( !JIO.isReady() ) alert('Not ready');
//// end init //// end init
//// Let's test! //// Let's test!
// JIO.loadDocument("SonNom"); JIO.loadDocument("SonNom");
JIO.saveDocument("Inside the document.","SonNom"); // JIO.saveDocument("Inside the document.","SonNom");
// JIO.saveDocument("Inside the document.","SonNom"); // JIO.saveDocument("Inside the document.","SonNom");
JIO.saveDocument("Inside the document.","SonNom2"); // JIO.saveDocument("Inside the document.","SonNom2");
// JIO.getDocumentList(); // JIO.getDocumentList();
// JIO.loadDocument("SonNom"); // JIO.loadDocument("SonNom");
// JIO.deleteDocument("SonNom"); // JIO.deleteDocument("SonNom");
......
...@@ -3,28 +3,64 @@ ...@@ -3,28 +3,64 @@
multiple storage backends using a common interface multiple storage backends using a common interface
*/ */
(function() { (function() {
/** ////////////////////////////////////////////////////////////////////////////
* load dependencies // Define constants
*/
var dependenceLoaded = function () { var C = {
try { 'METHOD_SAVE': 'save',
// check jQuery, sjcl & Base64 'METHOD_LOAD': 'load',
if (window.$ && window.sjcl && window.Base64) 'METHOD_GETLIST': 'getList',
return true; 'METHOD_DELETE': 'delete',
else return false; 'STATUS_INITIAL': 'initial',
} catch (e) { 'STATUS_DONE': 'done',
return false; 'STATUS_ONGOING': 'ongoing',
} 'STATUS_FAIL': 'fail',
'EVENT_PREFIX': 'jio:',
'EVENT_JOB_DONE': 'job_done',
'EVENT_JOB_FAIL': 'job_fail',
'EVENT_START_SAVING': 'start_saving',
'EVENT_STOP_SAVING': 'stop_saving',
'EVENT_START_LOADING': 'start_loading',
'EVENT_STOP_LOADING': 'stop_loading',
'EVENT_START_GETTINGLIST': 'start_gettinglist',
'EVENT_STOP_GETTINGLIST': 'stop_gettinglist',
'EVENT_START_DELETING': 'start_deleting',
'EVENT_STOP_DELETING': 'stop_deleting',
'FUNC_SAVE':'saveDocumentFromJob',
'FUNC_LOAD':'loadDocumentFromJob',
'FUNC_GETLIST':'getListFromJob',
'FUNC_DELETE':'deleteDocumentFromJob',
'DEFAULT_INTERVAL_DELAY': 100
}; };
C['DEFAULT_CONST_OBJECT'] = {};
C['DEFAULT_CONST_OBJECT'][C.METHOD_SAVE] = {
'STARTEVENT':C.EVENT_START_SAVING,
'STOPEVENT':C.EVENT_STOP_SAVING,
'FUNC':C.FUNC_SAVE};
C['DEFAULT_CONST_OBJECT'][C.METHOD_LOAD] = {
'STARTEVENT':C.EVENT_START_LOADING,
'STOPEVENT':C.EVENT_STOP_LOADING,
'FUNC':C.FUNC_LOAD};
C['DEFAULT_CONST_OBJECT'][C.METHOD_GETLIST] = {
'STARTEVENT':C.EVENT_START_GETTINGLIST,
'STOPEVENT':C.EVENT_STOP_GETTINGLIST,
'FUNC':C.FUNC_GETLIST};
C['DEFAULT_CONST_OBJECT'][C.METHOD_DELETE] = {
'STARTEVENT':C.EVENT_START_DELETING,
'STOPEVENT':C.EVENT_STOP_DELETING,
'FUNC':C.FUNC_DELETE};
var storageTypeObject = {};
var queue = null; // the jobs manager var queue = null; // the jobs manager
var jioStorage = null; var jioStorage = null;
var applicant = null; var jioApplicant = null;
// TODO stock statusobject for this tab ? faster ? better ?
////////////////////////////////////////////////////////////////////////////
// JIO main object. Contains all IO methods
/**
* JIO main object. Contains all IO methods
*/
var JIO = { var JIO = {
listener: null, listener: null,
...@@ -39,10 +75,10 @@ ...@@ -39,10 +75,10 @@
// jioData: object containing storage informations // jioData: object containing storage informations
// {type:,userName:,etc} // {type:,userName:,etc}
// applicant: a string of the applicant name // applicant: a string of the applicant name
applicant = {"ID":applicant}; jioApplicant = {"ID":applicant};
if (!applicant && !userName) return false; // TODO to know: return false or alert user ? if (!applicant) return false; // TODO to know: return false or alert user ?
if (!dependenceLoaded()) { if (!dependenceLoaded()) {
setTimeout(function() {JIO.initialize(jioData, applicant)},50); setTimeout(function() {JIO.initialize(jioData, jioApplicant)},50);
} else { } else {
switch(typeof jioData) { switch(typeof jioData) {
case "string" : case "string" :
...@@ -58,9 +94,12 @@ ...@@ -58,9 +94,12 @@
alert("Error while getting jio.json content"); alert("Error while getting jio.json content");
break; break;
} }
queue = new JIO.MessageQueue(); this.addStorageType('local',function (stor,app) {
this.listener = new JIO.JobListener(100); return new JIO.LocalStorage(stor,app);
this.listener.listen(); });
queue = new JIO.JobQueue();
this.listener = new JIO.JobListener(C.DEFAULT_INTERVAL_DELAY);
this.listener.start();
} }
}, },
...@@ -75,26 +114,22 @@ ...@@ -75,26 +114,22 @@
userNameAvailable: function(name, options) { userNameAvailable: function(name, options) {
// return this.storage.userNameAvailable(name, options !== undefined ? options : {}); // return this.storage.userNameAvailable(name, options !== undefined ? options : {});
}, },
loadDocument: function(fileName, options) { loadDocument: function(fileName) {
alert ('niy'); return queue.addJob (jioStorage,
// return this.jioMessage.postMessage ( new JIO.Job(C.METHOD_LOAD,fileName));
// {"method":"load","fileName":fileName,"status":"initial"},
// options);
}, },
saveDocument: function(data, fileName, options) { saveDocument: function(fileContent, fileName) {
console.log ('saveDoc'); return queue.addJob (jioStorage,
return queue.pushMessage (jioStorage, new JIO.Job(C.METHOD_SAVE,fileName,fileContent));
{"method":"save","fileName":fileName,"fileContent":data,"status":"initial"},
options);
}, },
deleteDocument: function(fileName, options) { deleteDocument: function(fileName, options) {
alert ('niy'); console.error ('niy');
// return this.jioMessage.postMessage ( // return this.jioMessage.postMessage (
// {"method":"delete","fileName":fileName,"status":"initial"}, // {"method":"delete","fileName":fileName,"status":"initial"},
// options); // options);
}, },
getDocumentList: function(options) { getDocumentList: function(options) {
alert ('niy'); console.error ('niy');
// return this.jioMessage.postMessage ( // return this.jioMessage.postMessage (
// {"method":"getList","status":"initial"}, // {"method":"getList","status":"initial"},
// options); // options);
...@@ -108,10 +143,25 @@ ...@@ -108,10 +143,25 @@
}, },
unsubscribe: function(event) { unsubscribe: function(event) {
pubSub.unsubscribe(event); pubSub.unsubscribe(event);
},
getApplicant: function() {
return jioApplicant;
},
getConstantObject: function() {
return C;
},
addStorageType: function(newType,storageCreator) {
storageTypeObject[newType] = storageCreator;
} }
} }
/*************************************************************************
******************************** Events *********************************/ // End JIO object
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Publisher Subscriber
var pubSub = new function () { var pubSub = new function () {
var topics = {}; var topics = {};
...@@ -132,21 +182,26 @@ ...@@ -132,21 +182,26 @@
return topic; return topic;
} }
this.publish = function (eventname,obj) { this.publish = function (eventname,obj) {
$.JIOPubSub('jio:'+eventname).publish(obj); $.JIOPubSub(C.EVENT_PREFIX + eventname).publish(obj);
}, },
this.subscribe = function (eventname,func) { this.subscribe = function (eventname,func) {
$.JIOPubSub('jio:'+eventname).subscribe(func); $.JIOPubSub(C.EVENT_PREFIX + eventname).subscribe(func);
}, },
this.unsubscribe = function (eventname) { this.unsubscribe = function (eventname) {
$.JIOPubSub('jio:'+eventname).unsubscribe(); $.JIOPubSub(C.EVENT_PREFIX + eventname).unsubscribe();
} }
}; };
// End Publisher Subscriber
////////////////////////////////////////////////////////////////////////////
/************************************************************************* ////////////////////////////////////////////////////////////////////////////
************************ JIO Job Listener *******************************/ // JIO Job Listener
JIO.JobListener = function (interval) { JIO.JobListener = function (interval) {
this.interval = interval; // A little daemon which will start jobs from the joblist
this.interval = (interval ? interval : 200);
this.id = null; this.id = null;
}; };
...@@ -162,12 +217,11 @@ ...@@ -162,12 +217,11 @@
/** /**
* Wait for jobs in the joblist inside the localStorage * Wait for jobs in the joblist inside the localStorage
*/ */
listen: function () {this.id = setInterval (function(){ start: function () {this.id = setInterval (function(){
// if there are jobs // if there are jobs
if (getJobArrayFromLocalStorage().length > 0) { if (localStorage.joblist &&
console.log ('listen'); localStorage.joblist !== '[]') {
queue.doAll(); queue.invokeAll();
} }
},this.interval);}, },this.interval);},
...@@ -175,13 +229,17 @@ ...@@ -175,13 +229,17 @@
* Stop the listener * Stop the listener
*/ */
stop: function () { stop: function () {
console.log ('stop listening');
clearInterval (this.id); clearInterval (this.id);
this.id = null; this.id = null;
} }
}; };
/************************************************************************* // End Job Listener
****************************** Messages *********************************/ ////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Job & JobQueue
/** /**
* Function parameters * Function parameters
...@@ -192,98 +250,81 @@ ...@@ -192,98 +250,81 @@
* May be a 'string' or an 'object' * May be a 'string' or an 'object'
*/ */
JIO.MessageQueue = function () { JIO.Job = function (method,filename,filecontent) {
// Job Constructor & initializer
return {'id':0,'method':method,'fileName':filename,
'fileContent':filecontent,'status':C.STATUS_INITIAL};
};
JIO.JobQueue = function () {
//// set first job ID //// set first job ID
this.jobid = 1; this.jobid = 1;
var localjoblist = getJobArrayFromLocalStorage(); var localjoblist = getJobArrayFromLocalStorage();
if (localjoblist.length > 0) { if (localjoblist.length > 0) {
this.jobid = localjoblist[localjoblist.length - 1].id + 1; this.jobid = localjoblist[localjoblist.length - 1].id + 1;
} };
localjoblist = null; // it is not necessary to fill memory with
// job remaining object // unused vars
this.remaining = {'save':0,'load':0,'delete':0,'getList':0};
// current job array, it is necessary even if 'ongoing' status exists. // reset all jobs' status to initial
// because if we close and re-open browser during an action, the job this.resetAll();
// will stay in 'ongoing' status, but all jobs are terminated.
this.currentjobarray = [];
this.status = {'save':'done','load':'done','delete':'done','getList':'done'};
// subscribe an event var returnedJobAnalyse = function (job) {
var t = this; // analyse the [job]
JIO.subscribe ('job_terminated', function (o) {
// check result of a terminated job
console.log ('job_terminated received');
var checkremaining = function(method) {
var cpt = 0;
for (var i in t.currentjobarray) {
if (t.currentjobarray[i].method === method) cpt ++;
}
return cpt;
};
objectDump(o);
//// remove in current jobarray
var newcurrentjobarray = [];
for (var i in t.currentjobarray) {
if (t.currentjobarray[i].id !== o.job.id)
newcurrentjobarray.push(t.currentjobarray[i]);
}
t.currentjobarray = newcurrentjobarray;
//// end removing
//// analysing job method //// analysing job method
switch (o.job.method) { if (!C.DEFAULT_CONST_OBJECT[job.method])
case 'save': return false;
if (checkremaining('save') === 0) { if (!ifRemainingJobs(job.method)) {
t.status.save = 'done'; var statusobject = getStatusObjectFromLocalStorage();
JIO.publish ('stop_saving'); statusobject[job.method] = C.STATUS_DONE;
} setStatusObjectToLocalStorage(statusobject);
break; switch (job.method) {
case 'load': case C.METHOD_GETLIST:
if (checkremaining('load') === 0) JIO.publish ('stop_loading'); // TODO merge list if necessary (we can create
break; // this.getList, deleted after sending the event,
case 'delete': // filled with done event) -> merge here or show
if (checkremaining('delete') === 0) JIO.publish ('stop_deleting');
break;
case 'getList':
if (checkremaining('getList') === 0) {
// TODO merge list if necessary (we can create this.getList,
// deleted after sending the event) -> merge here or show
// possible actions (manually, auto, ...) // possible actions (manually, auto, ...)
JIO.publish (C.DEFAULT_CONST_OBJECT[job.method].STOPEVENT/*, merged list*/);
JIO.publish ('stop_gettinglist',o.getList); // deleting list
return;
default: // if it was not a specific method
JIO.publish (C.DEFAULT_CONST_OBJECT[job.method].STOPEVENT);
return;
} }
break;
} }
//// end analyse //// end analyse
};
//// subscribe an event
var t = this;
JIO.subscribe (C.EVENT_JOB_DONE, function (job) {
//// check result console.log (C.EVENT_JOB_DONE+'_received');
if (o.job.status !== 'done') { // if it failed t.done(job);
t.fail(o.job); returnedJobAnalyse (job);
} else { // if done
t.done(o.job);
}
//// end check result
}); });
// // do all jobs at start, event the failed job JIO.subscribe (C.EVENT_JOB_FAIL, function (job) {
// this.doAll ({'checkstatus':function(){return true;}});
console.log (C.EVENT_JOB_FAIL+'_received');
t.fail(job);
returnedJobAnalyse (job);
});
//// end subscribing
}; };
JIO.MessageQueue.prototype = { JIO.JobQueue.prototype = {
pushMessage: function (storage,job) { addJob: function (storage,job) {
// Add a job to the Job list // Add a job to the Job list
// storage : the storage object // storage : the storage object
// job : the job object // job : the job object (may be a 'string')
console.log ('addJob');
//// Adding job to the list in localStorage //// Adding job to the list in localStorage
if (!job) return false;
// transforming job to an object // transforming job to an object
if ((typeof job) === 'string') job = JSON.parse(job); if ((typeof job) === 'string') job = JSON.parse(job);
// create joblist in local storage if unset // create joblist in local storage if unset
...@@ -293,87 +334,78 @@ ...@@ -293,87 +334,78 @@
this.jobid ++; this.jobid ++;
// set job storage // set job storage
job.storage = storage; job.storage = storage;
// post the message // save the new job
var localjoblist = getJobArrayFromLocalStorage(); var localjoblist = getJobArrayFromLocalStorage();
localjoblist.push(job); localjoblist.push(job);
setJobArrayToLocalStorage (localjoblist); setJobArrayToLocalStorage (localjoblist);
//// job added //// job added
}, // end pushMessage }, // end addJob
doAll: function (options) { resetAll: function () {
// reset All job to 'initial'
console.log ('resetAll');
var jobarray = getJobArrayFromLocalStorage();
for (var i in jobarray) {
jobarray[i].status = C.STATUS_INITIAL;
}
setJobArrayToLocalStorage(jobarray);
},
invokeAll: function () {
// Do all jobs in the list // Do all jobs in the list
// options : object containing
// checkstatus: function (job) {
// true if we can do the job, otherwise false }
console.log ('doAll');
//// check options, and set default settings if not set yet
options = checkOptions(options,{'checkstatus':function(status){
return (status === 'initial');}});
//// do All jobs //// do All jobs
jobarray = getJobArrayFromLocalStorage(); var jobarray = getJobArrayFromLocalStorage();
for (var i in jobarray) { for (var i in jobarray) {
if (options.checkstatus(jobarray[i].status)) { if (jobarray[i].status === C.STATUS_INITIAL) {
this.currentjobarray.push (jobarray[i]); jobarray[i].status = C.STATUS_ONGOING;
console.log ('ongoing'); this.invoke(jobarray[i]);
jobarray[i].status = 'ongoing';
setJobArrayToLocalStorage(jobarray);
objectDump(localStorage);
this.do(jobarray[i]);
} }
} }
setJobArrayToLocalStorage(jobarray);
//// end, continue doing jobs asynchronously //// end, continue doing jobs asynchronously
}, },
do: function (job) { invoke: function (job) {
console.log ('do');
// Do a job // Do a job
console.log ('invoke');
//// analysing job method //// analysing job method
switch (job.method) { // browsing methods
case 'save': if (!C.DEFAULT_CONST_OBJECT[job.method])
if (this.status.save === 'done') { // TODO do an appropriate error reaction ? unknown job method
this.status.save = 'ongoing'; return false;
JIO.publish ('start_saving',{'job':job}); var statusobject = getStatusObjectFromLocalStorage ();
} objectDump(statusobject);
createStorage(job.storage).saveDocumentFromJob(job); if (statusobject[job.method] === C.STATUS_DONE) {
break; statusobject[job.method] = C.STATUS_ONGOING;
case 'load': setStatusObjectToLocalStorage(statusobject);
break; JIO.publish (C.DEFAULT_CONST_OBJECT[job.method].STARTEVENT);
case 'delete':
break;
case 'getList':
break;
default:
// TODO do an appropriate error reaction : unknown job method
alert ('Unknown job method: ' + job.method);
this.fail (job);
break;
} }
// create an object and use it to save,load,...!
createStorageObject(job.storage,jioApplicant)[
C.DEFAULT_CONST_OBJECT[job.method].FUNC
](job,true); // overwrite
//// end method analyse //// end method analyse
}, },
done: function (job) { done: function (job) {
// This job is supposed done, we can remove it from localStorage. // This job is supposed done, we can remove it from localStorage.
console.log ('done');
var localjoblist = getJobArrayFromLocalStorage (); var localjoblist = getJobArrayFromLocalStorage ();
var newjoblist = []; // remove the job from the job list
//// find this unique job inside the list localjoblist = arrayRemoveValues (localjoblist,function (o) {
for (var i in localjoblist) { return (o.id === job.id);
// if found, it won't be in newjoblist });
if (localjoblist[i].id !== job.id) {
// not found, add to the new list
newjoblist.push ( localjoblist[i] );
}
}
//// job supposed found
// save to local storage // save to local storage
setJobArrayToLocalStorage (newjoblist); setJobArrayToLocalStorage (localjoblist);
}, },
fail: function (job) { fail: function (job) {
// This job cannot be done, change its status into localStorage. // This job cannot be done, change its status into localStorage.
console.log ('fail');
var localjoblist = getJobArrayFromLocalStorage (); var localjoblist = getJobArrayFromLocalStorage ();
//// find this unique job inside the list //// find this unique job inside the list
...@@ -391,37 +423,37 @@ ...@@ -391,37 +423,37 @@
// Clean the job list, removing all jobs that have failed. // Clean the job list, removing all jobs that have failed.
// It also change the localStorage Job list // It also change the localStorage Job list
// TODO setJobArrayToLocalStorage(
alert ('niy'); arrayRemoveValues(
getJobArrayFromLocalStorage(),
function(j){return (j.status === C.STATUS_FAIL);}
)
);
} }
}; // end JIO.MessageQueue }; // end JIO.JobQueue
// End Job & JobQueue
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// LOCAL STORAGE
/*************************************************************************
************************* specific storages *****************************/
/************************************************************
*********************** LocalStorage ************************/
/** /**
* Class LocalStorage * Class LocalStorage
* @class provides usual API to save/load/delete documents on the localStorage * @class provides usual API to save/load/delete documents on the localStorage
* @param data : object containing every element needed to build the storage : * @param storagedata : object containing every element needed to build the storage
* "userName" : the name of the user
* @param applicant : object containing inforamtion about the person/application needing this JIO object * @param applicant : object containing inforamtion about the person/application needing this JIO object
*/ */
JIO.LocalStorage = function(data) { JIO.LocalStorage = function(storagedata,applicant) {
this.applicant = applicant;
//// check user's localStorage part //// check user's localStorage part
this.userName = data.userName; this.userName = storagedata.userName;
if(!localStorage.getItem(this.userName)) { if(!localStorage.getItem(this.userName)) {
localStorage[this.userName] = '{}'; // Create user localStorage[this.userName] = '{}'; // Create user
} }
//// end check //// end check
//// loading documents
this.documents = JSON.parse(localStorage.getItem(this.userName)); //load documents
} }
JIO.LocalStorage.prototype = { JIO.LocalStorage.prototype = {
...@@ -430,163 +462,188 @@ ...@@ -430,163 +462,188 @@
* @param name : the name you want to check * @param name : the name you want to check
* @return true if the name is free, false otherwise * @return true if the name is free, false otherwise
*/ */
userNameAvailable: function(name) {if (localStorage[name]) return false; return true;}, userNameAvailable: function(name) {
if (localStorage[name]) return false;
return true;
},
getDocumentsFromLocalStorage: function() {
return JSON.parse(localStorage[this.userName]);
},
/** writeToLocalStorage: function(documents) {
* load a document in the storage localStorage[this.userName] = JSON.stringify(documents);
* @param fileName : the name of the file where the data will be stored }
* @param option : optional object containing }
* "success" : the function to execute when the load is done
* "errorHandler" : the function to execute if an error occures
* @return the content of the document
*/
loadDocument: function(fileName, options) {
options = checkOptions(options,{'onsuccess':function(){},
'onerror':function(){}});
if(!this.documents[fileName]) {
options.onerror({'status': 404,'message': "Document not found."});
return {'status':'fail','message': "Document not found."};
} else {
options.onsuccess({'status':'success','message':''});
return {'status':'success','message':''};
}
}, // end loadDocument
/** /**
* save a document in the local storage from a job * save a document in the local storage from a job
* @param job : contains all the information to save the document * @param job : contains all the information to save the document
* @param options : optional object containing * @param overwrite : a boolean set to true if the document has to be overwritten
* overwrite : a boolean set to true if the document has to be overwritten */
*/ JIO.LocalStorage.prototype[C.FUNC_SAVE] = function(job, overwrite) {
saveDocumentFromJob: function(job, options) { var t = this;
console.log ('saving'); // wait a little in order to let some other instructions to continue
var t = this; setTimeout(function () {
// wait a little in order to let some other instructions to continue var documents = t.getDocumentsFromLocalStorage();
setTimeout(function () {
// TODO check modification date !!!
options = checkOptions(options,{'overwrite':true});
if(!t.documents[job.fileName]) { // create document if(!documents[job.fileName]) { // create document
t.documents[job.fileName] = { documents[job.fileName] = {
'fileName': job.fileName, 'fileName': job.fileName,
'content': job.fileContent, 'content': job.fileContent,
'creationDate': Date.now(), 'creationDate': Date.now(),
'lastModified': Date.now() 'lastModified': Date.now()
} }
t.writeToLocalStorage(); t.writeToLocalStorage();
job.status='done'; job.status=C.STATUS_DONE;
job.message='success';
JIO.publish(C.EVENT_JOB_DONE,job);
return;
} else {
if(overwrite === true) { // overwrite
documents[job.fileName].lastModified = Date.now();
documents[job.fileName].content = job.fileContent;
t.writeToLocalStorage(documents);
job.status=C.STATUS_DONE;
job.message='success'; job.message='success';
JIO.publish(C.EVENT_JOB_DONE,job);
return;
} else { } else {
if(options.overwrite) { // overwrite job.status=C.STATUS_FAIL;
t.documents[job.fileName].lastModified = Date.now(); job.message='Document already exists.';
t.documents[job.fileName].content = job.fileContent; job.errno=403;
t.writeToLocalStorage(); JIO.publish(C.EVENT_JOB_FAIL,job);
job.status='done'; return;
job.message='success';
} else {
job.status='fail';
job.message='Document already exists.';
job.errno=403;
}
} }
JIO.publish('job_terminated',{'job':job});
}, 100);
return;
}, // end saveDocumentFromJob
/**
* Delete a document or a list of documents from the storage
* @param fileName : fileName to delete
* @param options : optional object containing
* "onsuccess" : the function to execute when the delete is done
* "onerror" : the function to execute if an error occures
*/
deleteDocument: function(fileName, options) {
options = checkOptions (options, {'onsuccess': function () {},
'onerror': function () {}});
if (typeof this.documents[fileName] !== 'object') {
options.onerror({'status':404,'message':'Document does not exists.'});
return {'status':'fail','message':'Document does not exists.'};
} }
delete this.documents[fileName]; }, C.DEFAULT_INTERVAL_DELAY);
this.save(); return;
options.onsuccess({'status':'success','message':''}); } // end saveDocumentFromJob
return {'status':'success','message':''};
},
/** /**
* load the list of the documents in this storage * load a document in the storage, copy the content into the job,
* @param options : optional object containing * then the function sends the job with an event.
* "onsuccess" : the function to execute when the load is done * @param job : the job that contains all informations about
* "onerror" : the function to execute if an error occures * loading operation.
*/ */
getDocumentList: function(options) { JIO.LocalStorage.prototype[C.FUNC_LOAD] = function(job) {
options = checkOptions (options,{'onsuccess':function(){}, var t = this;
'onerror':function(){}}); // wait a little in order to let some other instructions to continue
// var list = copy(this.documents); setTimeout(function () {
// if(option.success) option.success(list); var documents = t.getDocumentsFromLocalStorage();
// return list; if(!documents[job.fileName]) {
var list = []; job.status=C.STATUS_FAIL;
for (var key in this.documents) { job.errno=404;
list.push ({ job.message='Document not found.';
'fileName':this.documents[key].fileName, JIO.publish (C.EVENT_JOB_FAIL,job);
'creationDate':this.documents[key].creationDate, } else {
'lastModified':this.documents[key].lastModified job.status=C.STATUS_DONE;
job.file=documents[job.fileName];
job.message='success';
JIO.publish (C.EVENT_JOB_DONE,job);
}
}, C.DEFAULT_INTERVAL_DELAY)
}; // end loadDocumentFromJob
/**
* load the list of the documents in this storage
* @param job : the job that contains all informations about
* getting list operation.
*/
JIO.LocalStorage.prototype[C.FUNC_GETLIST] = function(job) {
// TODO update it
var t = this;
setTimeout(function () {
var documents = t.getDocumentsFromLocalStorage();
job.list = [];
for (var key in documents) {
job.list.push ({
'fileName':documents[key].fileName,
'creationDate':documents[key].creationDate,
'lastModified':documents[key].lastModified
}); });
} }
options.onsuccess({'status':'success','message':'','list':list,'length':list.length}); JIO.publish (C.EVENT_JOB_DONE,job);
return {'status':'success','message':'','list':list,'length':list.length}; }, C.DEFAULT_INTERVAL_DELAY);
}, }; // end getListFromJob
/**
* Delete a document or a list of documents from the storage
* @param fileName : fileName to delete
* @param options : optional object containing
*/
JIO.LocalStorage.prototype[C.FUNC_DELETE] = function(job) {
// TODO update it
var t = this;
setTimeout (function () {
var documents = t.getDocumentsFromLocalStorage();
// TODO is it realy a problem if we try to delete a deleted file ?
if (!documents[job.fileName]) {
job.status = C.STATUS_FAIL;
job.errno = 404;
job.message = 'Document not found.';
JIO.publish (C.EVENT_JOB_FAIL,job);
return;
}
delete documents[job.fileName];
t.writeToLocalStorage(documents);
job.status = C.STATUS_DONE;
job.message = 'success';
JIO.publish (C.EVENT_JOB_DONE,job);
return;
}, C.DEFAULT_INTERVAL_DELAY);
}; // end deleteDocumentFromJob
writeToLocalStorage: function() { // END LOCAL STORAGE
localStorage[this.userName] = JSON.stringify(this.documents); ////////////////////////////////////////////////////////////////////////////
}
}
/////////// ///////////
// Tools // // Tools //
/////////// ///////////
var dependenceLoaded = function () {
// tests if the dependencies are loaded
try {
// check jQuery
if ($)
return true;
else return false;
} catch (e) {
return false;
}
};
var ifRemainingJobs = function(method) {
// check if it remains [method] jobs (save,load,...)
// method : can me 'string' or 'undefined'
// undefined -> test if there is at least one job
// string -> test if there is at least one [method] job
if (!method) return (localStorage.joblist !== '[]');
joba = getJobArrayFromLocalStorage();
for (var k in joba) {
if (joba[k].method === method &&
joba[k].status !== C.STATUS_FAIL) return true;
}
return false;
};
/** /**
* Create a tree node from data * Create a storage with [data] informations
* @param data : information found in jio.json and needed to create the storage * @param data : information found in jio.json and needed to create the storage
* @param applicant : (optional) information about the person/application needing this JIO object (allow limited access) * @param applicant : information about the person/application needing this JIO object (allow limited access)
*/ */
function createStorage(data) { function createStorageObject(data,applicant) {
switch(data.type) { if (!storageTypeObject[data.type])
case "dav":return new JIO.DAVStorage(data);break; return null; // error!
case "local":return new JIO.LocalStorage(data);break; return storageTypeObject[data.type](data,applicant);
case "index":return new JIO.IndexedStorage(data);break;
case "multiple":return new JIO.MultipleStorage(data);break;
case "replicate":return new JIO.ReplicateStorage(data);break;
case "encrypt":return new JIO.CryptedStorage(data);break;
//etc
default:
// var waitedNode = null;//create a custom storage from a js file
// $.ajax({
// url: data.location+"/storage-init.js",//url of the file describing the creation of the storage
// type: "GET",
// async: false,
// dataType: "script",
// success: function(script) {
// var CustomStorage = eval(script);
// waitedNode = new CustomStorage(data)
// },
// error: data.errorHandler !== undefined ?
// data.errorHandler :
// function(type) {
// alert("Error "+type.status+
// " : fail while trying to instanciate storage"+
// data.location);
// }
// });
// return waitedNode;
break;
}
} }
var checkOptions = function (current,defaultopts) { var checkOptionObject = function (current,defaultopts) {
if(!current) { if(!current) {
return defaultopts; return defaultopts;
} }
...@@ -603,15 +660,48 @@ ...@@ -603,15 +660,48 @@
localjoblist = JSON.parse(localStorage.joblist); localjoblist = JSON.parse(localStorage.joblist);
return localjoblist; return localjoblist;
}; };
var setJobArrayToLocalStorage = function (jobarray) { var setJobArrayToLocalStorage = function (jobarray) {
localStorage.joblist = JSON.stringify(jobarray); localStorage.joblist = JSON.stringify(jobarray);
}; };
// TESTS var getStatusObjectFromLocalStorage = function () {
var tmp = {};
if (localStorage.status) {
tmp = JSON.parse (localStorage.status);
} else {
for (var Method in C.DEFAULT_CONST_OBJECT) {
tmp[Method] = C.STATUS_DONE;
}
}
return tmp;
};
var setStatusObjectToLocalStorage = function (statusobject) {
localStorage.status = JSON.stringify(statusobject);
};
var arrayRemoveValues = function (a,testfunc) {
// Removes the values from [a] where [testfunc(value)] returns true.
var isArray = function (a) {
return Object.prototype.toString.apply(a) === '[object Array]';
};
if (!isArray(a)) return a;
var na = [];
for (var k in a) {
if (!testfunc(a[k]))
na.push (a[k]);
}
return na;
};
// TODO DEBUG we can remove this function
var objectDump = function (o) { var objectDump = function (o) {
console.log (JSON.stringify(o)); console.log (JSON.stringify(o));
}; };
window.JIO = JIO;//the name to use for the framework. Ex : JIO.initialize(...), JIO.loadDocument... // the name to use for the framework. Ex : JIO.initialize(...), JIO.loadDocument...
window.JIO = JIO;
})(); })();
// There's only one comment at the top (and the bottom) of this file!
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