Commit c96a5bc7 authored by Tristan Cavelier's avatar Tristan Cavelier Committed by Sebastien Robin

Improve Tests for job management.

parent 8d661832
......@@ -10,19 +10,12 @@
<script type="text/javascript" src="js/jquery/jquery.js"></script>
<script type="text/javascript" src="unhosted/localorcookiestorage.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/jio.storage.js"></script>
<script type="text/javascript" >
$.ajax ({
url: 'responsexml/davsave',
dataType: 'text',
success:function () {
console.log ('bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb');
}
});
for (var i = 0; i < 300; i++) {
console.log ('a');
}
<script type="text/javascript">
<!--
var j = JIO.createNew();
//-->
</script>
</body>
</html>
......@@ -81,9 +81,8 @@ test ('All tests', function () {
// It is simple tests, but they will be used by replicate storage later
// for sync operation.
var o = {}; var clock = this.sandbox.useFakeTimers();
var t = this;
var mytest = function (message,method,retmethod,value){
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,method,retmethod,value){
o.f = function (result) {
deepEqual (result[retmethod],value,message);};
t.spy(o,'f');
......@@ -131,6 +130,52 @@ test ('All tests', function () {
o.jio.stop();
});
module ( 'Jio Job Managing' );
test ('Add 2 same jobs', function () {
// Check possibilities when adding 2 same jobs.
var o = {}, clock = this.sandbox.useFakeTimers(), id = 0;
// Test if the second job write over the first one
o.jio = JIO.createNew({'type':'dummyallok','userName':'dummy'},
{'ID':'jiotests'});
id = o.jio.id;
o.jio.saveDocument({'fileName':'file','fileContent':'content'});
clock.tick(10);
o.jio.saveDocument({'fileName':'file','fileContent':'content'});
deepEqual(LocalOrCookieStorage.getItem(
'jio/jobObject/'+id)['1'].date,10,
'The first job date have to be equal to the second job date.');
o.jio.stop();
clock.tick(-10);
// Test if the second job doesn't erase the first ongoing one
o.jio = JIO.createNew({'type':'dummyallok','userName':'dummy'},
{'ID':'jiotests'});
id = o.jio.id;
o.jio.saveDocument({'fileName':'file','fileContent':'content'});
clock.tick(200);
o.jio.saveDocument({'fileName':'file','fileContent':'content'});
ok(LocalOrCookieStorage.getItem(
'jio/jobObject/'+id)['2'] &&
LocalOrCookieStorage.getItem(
'jio/jobObject/'+id)['1'].status === 'ongoing',
'The second job must not overwrite the first ongoing one.');
ok(LocalOrCookieStorage.getItem(
'jio/jobObject/'+id)['2'].status === 'wait' &&
LocalOrCookieStorage.getItem(
'jio/jobObject/'+id)['2'].waitingFor &&
LocalOrCookieStorage.getItem(
'jio/jobObject/'+id)['2'].waitingFor.jobID === '1',
'The second job must be waiting for the first to end');
o.jio.stop();
});
test ('Restore a previous waiting job', function () {
ok(false,'not implemented yet');
});
module ( 'Jio LocalStorage' );
test ('Check name availability', function () {
......@@ -138,10 +183,8 @@ test ('Check name availability', function () {
// We remove MrCheckName from local storage, and checking must return true.
// We now add MrCheckName to local storage, and checking must return false.
var o = {};
var clock = this.sandbox.useFakeTimers();
var t = this;
var mytest = function (value){
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (value){
o.f = function (result) {
deepEqual(result.isAvailable,value,'checking name availabality');};
t.spy(o,'f');
......@@ -172,19 +215,21 @@ test ('Document save', function () {
// We launch a saving to localstorage and we check if the file is
// realy saved. Then save again and check if
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (value,lm,cd){
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,value,lm,cd,tick){
var tmp;
o.f = function (result) {
deepEqual(result.isSaved,value,'saving document');};
deepEqual(result.isSaved,value,message);};
t.spy(o,'f');
o.jio.saveDocument(
{'fileName':'file','fileContent':'content','callback': o.f});
clock.tick(510);
if (tick === undefined) { clock.tick(510); }
else { clock.tick(tick); }
if (!o.f.calledOnce)
ok(false, 'no response / too much results');
else {
// check content
var tmp = LocalOrCookieStorage.getItem ('jio/local/MrSaveName/jiotests/file');
tmp = LocalOrCookieStorage.getItem ('jio/local/MrSaveName/jiotests/file');
deepEqual (tmp,{'fileName':'file','fileContent':'content',
'lastModified':lm,'creationDate':cd},'check content');
}
......@@ -195,10 +240,16 @@ test ('Document save', function () {
LocalOrCookieStorage.deleteItem ('jio/local/MrSaveName/jiotests/file');
// save and check document existence
clock.tick(200);
mytest(true,200,200); // value, lastmodified, creationdate
mytest('saving document',true,200,200); // value, lastmodified, creationdate
// re-save and check modification date
mytest(true,710,200); // 710 = 200 + 510 ms (clock tick)
// 710 = 200 + 510 ms (clock tick)
mytest('saving again',true,710,200);
// re-save and check modification date
// 1220 = 710 + 510 ms (clock tick)
clock.tick(-1000);
mytest('saving a older document',false,710,200,1510);
o.jio.stop();
});
......@@ -208,8 +259,9 @@ test ('Document load', function () {
// We launch a loading from localstorage and we check if the file is
// realy loaded.
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (res,value){
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
doc = {},
mytest = function (res,value){
o.f = function (result) {
deepEqual(result[res],value,'loading document');};
t.spy(o,'f');
......@@ -226,8 +278,8 @@ test ('Document load', function () {
mytest ('status','fail');
// re-load file after saving it manually
var doc = {'fileName':'file','fileContent':'content',
'lastModified':1234,'creationDate':1000};
doc = {'fileName':'file','fileContent':'content',
'lastModified':1234,'creationDate':1000};
LocalOrCookieStorage.setItem ('jio/local/MrLoadName/jiotests/file',doc);
mytest ('document',doc);
......@@ -238,12 +290,13 @@ test ('Get document list', function () {
// Test if LocalStorage can get a list of documents.
// We create 2 documents inside localStorage to check them.
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (value){
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
doc1 = {}, doc2 = {},
mytest = function (value){
o.f = function (result) {
var objectifyDocumentArray = function (array) {
var obj ={};
for (var k in array) {obj[array[k].fileName] = array[k];}
var obj = {}, k;
for (k in array) {obj[array[k].fileName] = array[k];}
return obj;
};
deepEqual (objectifyDocumentArray(result.list),
......@@ -257,10 +310,10 @@ test ('Get document list', function () {
};
o.jio = JIO.createNew({'type':'local','userName':'MrListName'},
{"ID":'jiotests'});
var doc1 = {'fileName':'file','fileContent':'content',
'lastModified':1,'creationDate':0};
var doc2 = {'fileName':'memo','fileContent':'test',
'lastModified':5,'creationDate':2};
doc1 = {'fileName':'file','fileContent':'content',
'lastModified':1,'creationDate':0};
doc2 = {'fileName':'memo','fileContent':'test',
'lastModified':5,'creationDate':2};
LocalOrCookieStorage.setItem ('jio/local/MrListName/jiotests/file',doc1);
LocalOrCookieStorage.setItem ('jio/local/MrListName/jiotests/memo',doc2);
delete doc1.fileContent;
......@@ -275,8 +328,8 @@ test ('Document remove', function () {
// We launch a remove from localstorage and we check if the file is
// realy removed.
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (){
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (){
o.f = function (result) {
deepEqual(result.isRemoved,true,'removing document');};
t.spy(o,'f');
......@@ -305,8 +358,8 @@ module ('Jio DAVStorage');
test ('Check name availability', function () {
// Test if DavStorage can check the availabality of a name.
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (value,errno) {
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (value,errno) {
var server = t.sandbox.useFakeServer();
server.respondWith ("PROPFIND",
"https://ca-davstorage:8080/dav/davcheck/",
......@@ -339,9 +392,9 @@ test ('Check name availability', function () {
test ('Document load', function () {
// Test if DavStorage can load documents.
var davload = getXML('responsexml/davload');
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (message,doc,errprop,errget) {
var davload = getXML('responsexml/davload'),
o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,doc,errprop,errget) {
var server = t.sandbox.useFakeServer();
server.respondWith (
"PROPFIND","https://ca-davstorage:8080/dav/davload/jiotests/file",
......@@ -382,10 +435,10 @@ test ('Document load', function () {
test ('Document save', function () {
// Test if DavStorage can save documents.
var davsave = getXML('responsexml/davsave');
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (message,value,errnoput,errnoprop,
lastmodified,overwrite,force) {
var davsave = getXML('responsexml/davsave'),
o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,value,errnoput,errnoprop,
overwrite,force,tick) {
var server = t.sandbox.useFakeServer();
server.respondWith (
// lastmodified = 7000, creationdate = 5000
......@@ -411,7 +464,6 @@ test ('Document save', function () {
t.spy(o,'f');
o.jio.saveDocument({'fileName':'file','fileContent':'content',
'options':{'force':force,'overwrite':overwrite},
'lastModified':lastmodified,
'callback':o.f});
clock.tick(500);
server.respond();
......@@ -431,33 +483,33 @@ test ('Document save', function () {
// 404 Not Found
// // the path does not exist, we want to create it, and save the file.
// mytest('create path if not exists, and create document',
// true,201,404,9999);
// true,201,404);
// the document does not exist, we want to create it
mytest('create document',
true,201,404,10000);
// the document already exists, we want to overwrite it
mytest('overwrite document',
true,204,207,10100,true);
// the document already exists, we don't want to overwrite it
mytest('do not overwrite document',
false,204,207,10200,false);
mytest('create document',true,201,404);
// the document is already exists, it is younger than the one we want
// to save.
mytest('younger than the one we want to save',
false,204,207,0,true,false);
false,204,207,true,false);
// the document is already exists, it is the youngest but we want to
// force overwriting
mytest('youngest but force overwrite',
true,204,207,0,true,true);
true,204,207,true,true);
clock.tick(8000);
// the document already exists, we want to overwrite it
mytest('overwrite document',
true,204,207,true);
// the document already exists, we don't want to overwrite it
mytest('do not overwrite document',
false,204,207,false);
o.jio.stop();
});
test ('Get Document List', function () {
// Test if DavStorage can get a list a document.
var davlist = getXML('responsexml/davlist');
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (message,value,errnoprop) {
var davlist = getXML('responsexml/davlist'),
o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,value,errnoprop) {
var server = t.sandbox.useFakeServer();
server.respondWith (
"PROPFIND",'https://ca-davstorage:8080/dav/davlist/jiotests/',
......@@ -494,8 +546,8 @@ test ('Get Document List', function () {
test ('Remove document', function () {
// Test if DavStorage can remove documents.
var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
var mytest = function (message,value,errnodel) {
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,value,errnodel) {
var server = t.sandbox.useFakeServer();
server.respondWith (
"DELETE","https://ca-davstorage:8080/dav/davremove/jiotests/file",
......@@ -518,3 +570,67 @@ test ('Remove document', function () {
mytest('remove an already removed document',true,404)
o.jio.stop();
});
module ('Jio ReplicateStorage');
test ('Check name availability', function () {
// Tests the replicate storage
// method : checkNameAvailability
// It will test all the possibilities that could cause a server,
// like synchronisation problem...
var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
mytest = function (message,value) {
o.f = function (result) {
deepEqual (result.isAvailable,value,message)};
t.spy(o,'f');
o.jio.checkNameAvailability({'userName':'Dummy','callback':o.f});
clock.tick(1000);
if (!o.f.calledOnce)
ok(false,'no respose / too much results');
};
// DummyStorageAllOK,OK
o.jio = JIO.createNew({'type':'replicate','storageArray':[
{'type':'dummyallok'},{'type':'dummyallok'}]},
{'ID':'jiotests'});
mytest('DummyStoragesAllOK,OK : name available',true);
o.jio.stop();
// DummyStorageAllOK,Fail
o.jio = JIO.createNew({'type':'replicate','storageArray':[
{'type':'dummyallok'},{'type':'dummyallfail'}]},
{'ID':'jiotests'});
mytest('DummyStoragesAllOK,Fail : name not available',false);
o.jio.stop();
// DummyStorageAllFail,OK
o.jio = JIO.createNew({'type':'replicate','storageArray':[
{'type':'dummyallfail'},{'type':'dummyallok'}]},
{'ID':'jiotests'});
mytest('DummyStoragesAllFail,OK : name not available',false);
o.jio.stop();
// DummyStorageAllFail,Fail
o.jio = JIO.createNew({'type':'replicate','storageArray':[
{'type':'dummyallfail'},{'type':'dummyallfail'}]},
{'ID':'jiotests'});
mytest('DummyStoragesAllFail,Fail : name not available',false);
o.jio.stop();
});
// test ('Document load', function () {
// // Test if DavStorage can load documents.
// var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
// var mytest = function (message,doc) {
// o.f = function (result) {
// deepEqual (result.document,doc,message);};
// t.spy(o,'f');
// o.jio.loadDocument({'fileName':'file','callback':o.f});
// clock.tick(1000);
// server.respond();
// if (!o.f.calledOnce)
// ok(false, 'no response / too much results');
// };
// o.jio = JIO.createNew({'type':'replicate','userName':'Dummy'},
// {'ID':'jiotests'});
// o.jio.stop();
// });
......@@ -2,13 +2,6 @@
;var JIO =
(function () {
// check dependencies
var errorDependencies=function(){console.error('Cannot find jQuery.');};
try{if(!(jQuery && LocalOrCookieStorage)){
errorDependencies();return null;
}}catch(e){
errorDependencies();return null;}
////////////////////////////////////////////////////////////////////////////
// constants
var jioConstObj = {
......@@ -34,33 +27,46 @@
'stop_event':'stop_removing',
'retvalue':'isRemoved' } // returns 'boolean'
}
};
},
// end constants
////////////////////////////////////////////////////////////////////////////
// jio globals
var jioGlobalObj = {
'localStorage': LocalOrCookieStorage, // where the browser stores data
jioGlobalObj = {
'localStorage': null, // where the browser stores data
'queueID': 1,
'storageTypeObject': {} // ex: {'type':'local','creator': fun ...}
};
},
// end jio globals
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Tools
var createStorageObject = function ( options ) {
checkJioDependencies = function() {
var retval = true,
err = function (name) {
console.error ('Fail to load ' + name);
retval = false;
};
try { if (!jQuery) { err('jQuery'); } }
catch (e) { err('jQuery'); }
try { if (!LocalOrCookieStorage) { err('LocalOrCookieStorage'); } }
catch (e) { err('LocalOrCookieStorage'); }
return retval;
},
createStorageObject = function ( options ) {
// Create a storage thanks to storages types set with 'addStorageType'.
if (!jioGlobalObj.storageTypeObject[ options.storage.type ])
return null; // error!
return jioGlobalObj.storageTypeObject[
options.storage.type ](options);
};
var getNewQueueID = function () {
},
getNewQueueID = function () {
// Returns a new queueID
var localStor = jioGlobalObj.localStorage.getAll();
for (var k in localStor) {
var splitk = k.split('/');
var localStor = jioGlobalObj.localStorage.getAll(), k = 'key',
splitk = ['splitedkey'], id = 0;
for (k in localStor) {
splitk = k.split('/');
if (splitk[0] === 'jio' &&
splitk[1] === 'id') {
if (JSON.parse(localStor[k]) < Date.now() - 10000) { // 10 sec ?
......@@ -71,20 +77,28 @@
}
}
}
var id = jioGlobalObj.queueID;
id = jioGlobalObj.queueID;
jioGlobalObj.queueID ++;
return id;
};
},
// end Tools
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Classes
PubSub,Job,JobQueue,JobListener,ActivityUpdater,JioCons,Jio;
// end Classes
////////////////////////////////////////////////////////////////////////////
// check dependencies
if (!checkJioDependencies()) { return; }
////////////////////////////////////////////////////////////////////////////
// Publisher Subcriber
var PubSub = function () {
var topics = {};
PubSub = function () {
var topics = {}, callbacks, topic;
this.eventAction = function (id) {
var callbacks;
var topic = id && topics[id];
topic = id && topics[id];
if (!topic) {
callbacks = $.Callbacks();
topic = {
......@@ -119,17 +133,17 @@
////////////////////////////////////////////////////////////////////////////
// Job & JobQueue
var Job = function ( options ) {
Job = function ( options ) {
// Job constructor
console.log ('Job');
var job = $.extend({},options);
job['id']=0;
job['status']='initial';
job['date']=Date.now();
return job;
};
var JobQueue = function ( publisher ) {
JobQueue = function ( publisher ) {
// JobQueue is a queue of jobs. It will regulary copy this queue
// into localStorage to resume undone tasks.
// pubsub: the publisher to use to send event
......@@ -170,10 +184,10 @@
isThereJobsWhere: function( func ) {
// Check if there is jobs, in the queue,
// where [func](job) == true.
if (!func)
return true;
for (var id in this.jobObject) {
var id = 'id';
if (!func) { return true; }
for (id in this.jobObject) {
if (func(this.jobObject[id]))
return true;
}
......@@ -185,11 +199,13 @@
return jioGlobalObj.localStorage.setItem(
this.jobObjectName,this.jobObject);
},
createJob: function ( options ) {
this.addJob ( new Job ( options ) );
},
addJob: function ( job ) {
// Add a job to the queue
// job : the job object
console.log ('addJob');
// set job id
job.id = this.jobid;
this.jobid ++;
......@@ -207,11 +223,9 @@
// options.job : the job object containing at least {id:..}.
// options.where : remove values where options.where(job) === true
console.log ('removeJob');
//// set tests functions
var settings = $.extend ({'where':function (job) {return true;}},
options);
var andwhere ;
options),k='key',andwhere,found=false;
if (settings.job) {
andwhere = function (job) {return (job.id===settings.job.id);};
} else {
......@@ -220,8 +234,7 @@
//// end set tests functions
//// modify the job list
var found = false;
for (var k in this.jobObject) {
for (k in this.jobObject) {
if (settings.where(this.jobObject[k]) &&
andwhere(this.jobObject[k]) ) {
delete this.jobObject[k];
......@@ -233,14 +246,12 @@
}
//// end modifying
this.copyJobQueueToLocalStorage();
console.log ('end removeJob');
},
resetAll: function () {
// Reset all job to 'initial'.
for (var id in this.jobObject) {
var id = 'id';
for (id in this.jobObject) {
this.jobObject[id].status = 'initial';
}
this.copyJobQueueToLocalStorage();
......@@ -249,9 +260,15 @@
invokeAll: function () {
// Do all jobs in the queue.
var i = 'id';
//// do All jobs
for (var i in this.jobObject) {
for (i in this.jobObject) {
if (this.jobObject[i].status === 'initial') {
// invoke new job
this.invoke(this.jobObject[i]);
} else if (this.jobObject[i].status === 'wait' &&
this.jobObject[i].retryAt >= Date.now()) {
// invoke waiting job
this.invoke(this.jobObject[i]);
}
}
......@@ -262,7 +279,8 @@
invoke: function (job) {
// Do a job invoking the good method in the good storage.
console.log ('invoke ' + JSON.stringify(job));
var t = this;
//// analysing job method
// if the method does not exist, do nothing
if (!jioConstObj.jobMethodObject[job.method])
......@@ -280,7 +298,6 @@
job.status = 'ongoing';
}
// Create a storage object and use it to save,load,...!
var t = this;
createStorageObject(
{'queue':this,
'storage':job.storage,
......@@ -295,7 +312,6 @@
// It is a callback function called just before user callback.
// It is called to manage jobObject according to the ended job.
console.log ('ended');
switch (job.status) {
case 'done':
// This job is supposed done, we can remove it from queue.
......@@ -341,7 +357,7 @@
////////////////////////////////////////////////////////////////////////////
// jio job listener
var JobListener = function ( queue ) {
JobListener = function ( queue ) {
// A little daemon which will start jobs from the joblist
this.interval = 200;
......@@ -358,16 +374,15 @@
start: function () {
// Start the listener. It will always check if there are jobs in the
// queue
var queue = this.queue;
if (!this.id) {
var queue = this.queue;
this.id = setInterval (function () {
// if there is jobs
if (JSON.stringify(queue.jobObject) !== '{}') {
queue.invokeAll();
}
},this.interval);
console.log ('listener started');
return true;
} else {
return false;
......@@ -375,7 +390,6 @@
},
stop: function () {
if (this.id) {
console.log ('listener stopped');
clearInterval (this.id);
this.id = null;
return true;
......@@ -388,7 +402,7 @@
////////////////////////////////////////////////////////////////////////////
// ActivityUpdater
var ActivityUpdater = function () {
ActivityUpdater = function () {
// The activity updater is a little thread that proves activity of this
// jio instance.
......@@ -398,10 +412,11 @@
ActivityUpdater.prototype = {
start: function (id) {
// start the updater
console.log ('start touching jio/id/'+id);
var t = this;
if (!this.id) {
this.touch(id);
var t = this;
this.id = setInterval (function () {
t.touch(id);
},this.interval);
......@@ -412,7 +427,6 @@
},
stop: function () {
// stop the updater
console.log ('stop touching');
if (this.id) {
clearInterval (this.id);
this.id = null;
......@@ -430,7 +444,7 @@
////////////////////////////////////////////////////////////////////////////
// JIO Constructor
var JioCons = function ( storage , applicant ) {
JioCons = function ( storage , applicant ) {
// JIO Constructor, create a new JIO object.
// It just initializes values.
// storage : the storage that contains {type:..,[storageinfos]}
......@@ -468,7 +482,6 @@
if (this.id !== 0) return false;
// set a new jio id
this.id = getNewQueueID();
console.log (this.id);
// initializing objects
this.queue.init({'jioID':this.id});
// start touching
......@@ -511,7 +524,6 @@
// obj : is an object containing some parameters for example
if (!this.isReady()) return ;
console.log ('publish ' + eventname);
return this.pubsub.publish(eventname,obj);
},
subscribe: function (eventname, callback) {
......@@ -521,13 +533,11 @@
// eventname : the event name.
// callback : called after receiving event.
console.log ('subscribe ' +eventname);
return this.pubsub.subscribe(eventname,callback);
},
unsubscribe: function (eventname,callback) {
// unsubscribe callback from an event
console.log ('unsubscribe ' +eventname);
return this.pubsub.unsubscribe(eventname,callback);
},
......@@ -545,7 +555,6 @@
// function (result) { alert('is available? ' +
// result.isAvailable); }});
if (!this.isReady()) return null;
var settings = $.extend ({
'userName': this.storage.userName,
'storage': this.storage,
......@@ -554,8 +563,9 @@
'callback': function () {}
},options);
// check dependencies
if (settings.userName && settings.storage && settings.applicant) {
return this.queue.addJob ( new Job ( settings ) );
if (this.isReady() && settings.userName &&
settings.storage && settings.applicant) {
return this.queue.createJob ( settings );
}
return null;
},
......@@ -572,19 +582,16 @@
// 'callback': function (result) { alert('saved?' +
// result.isSaved); }});
console.log ('saveDocument');
if (!this.isReady()) return null;
var settings = $.extend({
'storage': this.storage,
'lastModified': Date.now(),
'method':'saveDocument',
'applicant': this.applicant,
'callback': function () {}
},options);
// check dependencies
if (settings.fileName && settings.fileContent &&
if (this.isReady() && settings.fileName && settings.fileContent &&
settings.storage && settings.applicant) {
return this.queue.addJob ( new Job ( settings ) );
return this.queue.createJob ( settings );
}
return null;
},
......@@ -603,8 +610,6 @@
// result.doc.fileContent + ' creation date: ' +
// result.doc.creationDate); }});
console.log ('load');
if (!this.isReady()) return null;
var settings = $.extend ({
'storage': this.storage,
'applicant': this.applicant,
......@@ -612,8 +617,9 @@
'callback': function(){}
},options);
// check dependencies
if ( settings.fileName && settings.storage && settings.applicant) {
return this.queue.addJob ( new Job ( settings ) );
if (this.isReady() && settings.fileName &&
settings.storage && settings.applicant) {
return this.queue.createJob ( settings );
}
return null;
},
......@@ -628,8 +634,6 @@
// jio.getDocumentList({'callback':
// function (result) { alert('list: '+result.list); }});
console.log ('getList');
if (!this.isReady()) return null;
var settings = $.extend ({
'storage': this.storage,
'applicant': this.applicant,
......@@ -637,8 +641,8 @@
'callback':function(){}
},options);
// check dependencies
if ( settings.storage && settings.applicant ) {
return this.queue.addJob ( new Job ( settings ) );
if (this.isReady() && settings.storage && settings.applicant ) {
return this.queue.createJob( settings );
}
return null;
},
......@@ -653,16 +657,15 @@
// jio.removeDocument({'fileName':'file','callback':
// function (result) { alert('removed? '+result.isRemoved); }});
console.log ('removeDocument');
if (!this.isReady()) return null;
var settings = $.extend ({
'storage': this.storage,
'applicant': this.applicant,
'method':'removeDocument',
'callback':function (){}
},options);
if ( settings.fileName && settings.storage && settings.applicant ) {
return this.queue.addJob ( new Job( settings ) );
if (this.isReady() && settings.fileName &&
settings.storage && settings.applicant ) {
return this.queue.createJob ( settings );
}
return null;
}
......@@ -672,7 +675,7 @@
////////////////////////////////////////////////////////////////////////////
// Jio creator
var Jio = function () {
Jio = function () {
// Jio creator object
// this object permit to create jio object
};
......@@ -680,6 +683,10 @@
createNew: function ( storage, applicant) {
// return a new instance of JIO
if (jioGlobalObj.localStorage===null) {
jioGlobalObj.localStorage = LocalOrCookieStorage;
}
return new JioCons(storage,applicant);
},
addStorageType: function ( type, constructor ) {
......
......@@ -6,22 +6,39 @@
// - replicate
;(function ( Jio ) {
// check dependencies
var errorDependencies=function(){$.error('Cannot find Jio or Base64');};
try{if (!Jio || !Base64){
errorDependencies();return;
}} catch (e){
errorDependencies();return;}
////////////////////////////////////////////////////////////////////////////
// globals
var jioGlobalObj = Jio.getGlobalObject();
var jioGlobalObj = Jio.getGlobalObject(),
// end globals
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Tools
checkJioDependencies = function() {
var retval = true,
err = function (name) {
console.error ('Fail to load ' + name);
retval = false;
};
try { if (!Base64) { err('Base64'); } }
catch (e) { err('Base64'); }
return retval;
},
// end Tools
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Classes
LocalStorage,DAVStorage,ReplicateStorage;
// end Classes
////////////////////////////////////////////////////////////////////////////
// check dependencies
if (!checkJioDependencies()) { return; }
////////////////////////////////////////////////////////////////////////////
// Local Storage
var LocalStorage = function ( options ) {
LocalStorage = function ( options ) {
// LocalStorage constructor
// initializes the local storage for jio and create user if necessary.
......@@ -38,12 +55,14 @@
// returns {'status':string,'message':string,'isAvailable':boolean}
// in the jobendcallback arguments.
var available = true, localStor = null,
k = 'key', splitk = ['splitedkey'];
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
var available = true;
var localStor = jioGlobalObj.localStorage.getAll();
for (var k in localStor) {
var splitk = k.split('/');
localStor = jioGlobalObj.localStorage.getAll();
for (k in localStor) {
splitk = k.split('/');
if (splitk[0] === 'jio' &&
splitk[1] === 'local' &&
splitk[2] === job.userName) {
......@@ -81,22 +100,21 @@
// returns {'status':string,'message':string,'isSaved':boolean}
// in the jobendcallback arguments.
var settings = $.extend({'overwrite':true,
'force':false},job.options);
var t = this;
var settings = $.extend({
'overwrite':true,'force':false},job.options),
res = {}, doc = null;
// wait a little in order to simulate asynchronous saving
setTimeout (function () {
var res = {};
// reading
var doc = jioGlobalObj.localStorage.getItem(
doc = jioGlobalObj.localStorage.getItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName);
if (!doc) { // create document
doc = {
'fileName': job.fileName,
'fileContent': job.fileContent,
'creationDate': job.lastModified,
'lastModified': job.lastModified
'creationDate': job.date,
'lastModified': job.date
}
// writing
jioGlobalObj.localStorage.setItem(
......@@ -114,7 +132,7 @@
// if it doesn't force writing
// checking modification date
if ( ! settings.force &&
doc.lastModified >= job.lastModified ) {
doc.lastModified >= job.date ) {
// date problem!
// return
res.status = job.status = 'fail';
......@@ -126,7 +144,7 @@
return;
}
// overwriting
doc.lastModified = job.lastModified;
doc.lastModified = job.date;
doc.fileContent = job.fileContent;
// writing
jioGlobalObj.localStorage.setItem(
......@@ -163,11 +181,11 @@
// document object is {'fileName':string,'fileContent':string,
// 'creationDate':date,'lastModified':date}
var t = this;
// wait a little in order to simulate asynchronous operation
var t = this, res = {}, doc = null;
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
var res = {};
var doc = jioGlobalObj.localStorage.getItem(
doc = jioGlobalObj.localStorage.getItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName);
if (!doc) {
......@@ -202,13 +220,14 @@
// the list is [object,object] -> object = {'fileName':string,
// 'lastModified':date,'creationDate':date}
var t = this;
var t = this, res = {}, localStor = null, k = 'key',
splitk = ['splitedkey'];
setTimeout(function () {
var res = {};
var localStor = jioGlobalObj.localStorage.getAll();
localStor = jioGlobalObj.localStorage.getAll();
res.list = [];
for (var k in localStor) {
var splitk = k.split('/');
for (k in localStor) {
splitk = k.split('/');
if (splitk[0] === 'jio' &&
splitk[1] === 'local' &&
splitk[2] === job.storage.userName &&
......@@ -235,10 +254,10 @@
// returns {'status':string,'message':string,'isRemoved':boolean}
// in the jobendcallback arguments.
var t = this;
var t = this, res = {}, doc = null;
setTimeout (function () {
var res = {};
var doc = jioGlobalObj.localStorage.getItem(
doc = jioGlobalObj.localStorage.getItem(
'jio/local/'+job.storage.userName+'/'+job.applicant.ID+'/'+
job.fileName);
// already deleted
......@@ -263,19 +282,14 @@
return;
}, 100);
}
};
// add key to storageObjectType of global jio
Jio.addStorageType('local', function (options) {
return new LocalStorage(options);
});
},
// end Local Storage
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// DAVStorage
var DAVStorage = function ( options ) {
DAVStorage = function ( options ) {
};
DAVStorage.prototype = {
......@@ -287,17 +301,20 @@
// options.success: the function called if success
// options.userName: the username
// options.password: the password
// TODO this method is not working !!!
var settings = $.extend ({'success':function(){},
'error':function(){}},options);
var settings = $.extend ({
'success':function(){},'error':function(){}},options),
splitpath = ['splitedpath'], tmppath = 'temp/path', t = this;
// if pathstep is not defined, then split the settings.path
// and do mkcol recursively
if (!settings.pathsteps) {
settings.pathsteps = 1;
this.mkcol(settings);
} else {
var splitpath = settings.path.split('/');
splitpath = settings.path.split('/');
// // check if the path is terminated by '/'
// if (splitpath[splitpath.length-1] == '') {
// splitpath.length --;
......@@ -308,9 +325,8 @@
}
splitpath.length = settings.pathsteps + 1;
settings.pathsteps++;
var tmppath = splitpath.join('/');
tmppath = splitpath.join('/');
alert(settings.location + tmppath);
var t = this;
$.ajax ( {
url: settings.location + tmppath,
type: 'MKCOL',
......@@ -347,6 +363,8 @@
// returns {'status':string,'message':string,'isAvailable':boolean}
// in the jobendcallback arguments.
var res = {};
$.ajax ( {
url: job.storage.location + '/dav/' + job.storage.userName + '/',
......@@ -357,7 +375,6 @@
job.storage.userName + ':' +
job.storage.password ), Depth: '1'},
success: function (xmlData) {
var res = {};
res.status = job.status = 'done';
res.message = job.userName + ' is not available.';
res.isAvailable = false;
......@@ -365,7 +382,6 @@
job.callback(res);
},
error: function (type) {
var res = {};
switch(type.status){
case 404:
res.status = job.status = 'done';
......@@ -397,11 +413,11 @@
// returns {'status':string,'message':string,'isSaved':boolean}
// in the jobendcallback arguments.
var settings = $.extend ({'overwrite':true,
'force':false},job.options);
var res = {};
var settings = $.extend ({
'overwrite':true,'force':false},job.options), res = {},
t = this, tmpjob = {},
// TODO if path of /dav/user/applic does not exists, it won't work!
var saveOnDav = function () {
saveOnDav = function () {
//// save on dav
$.ajax ( {
url: job.storage.location + '/dav/' +
......@@ -439,8 +455,7 @@
}
//// start loading document
var t = this;
var tmpjob = $.extend({},job);
tmpjob = $.extend({},job);
tmpjob.callback = function(result) {
if(result.status === 'fail') {
switch (result.errno) {
......@@ -480,7 +495,7 @@
// TODO merge files
// Document already exists
if (settings.overwrite) { // overwrite
if (result.document.lastModified >= job.lastModified) {
if (result.document.lastModified >= job.date) {
// date ploblem !
res.status = job.status = 'fail';
res.message = 'Document is older than the '+
......@@ -517,9 +532,8 @@
// 'creationDate':date,'lastModified':date}
// TODO check if job's features are good
var res = {};
res.document = {};
var getContent = function () {
var res = {'document':{}},
getContent = function () {
$.ajax ( {
url: job.storage.location + '/dav/' +
job.storage.userName + '/' +
......@@ -597,6 +611,8 @@
// the list is [object,object] -> object = {'fileName':string,
// 'lastModified':date,'creationDate':date}
var res = {}, documentArrayList = [], file = {}, pathArray = [];
$.ajax ( {
url: job.storage.location + '/dav/' +
job.storage.userName + '/' + job.applicant.ID + '/',
......@@ -607,19 +623,16 @@
job.storage.userName + ':' +
job.storage.password ), Depth: '1'},
success: function (xmlData) {
var res = {};
var documentArrayList = [];
$("D\\:response",xmlData).each(function(i,data) {
if(i>0) { // exclude parent folder
var file = {};
var pathArray = ($($("D\\:href",
xmlData).get(i)).text()).split('/');
file = {};
pathArray = ($($("D\\:href",
xmlData).get(i)).text()).split('/');
file.fileName = (pathArray[pathArray.length-1] ?
pathArray[pathArray.length-1] :
pathArray[pathArray.length-2]+'/');
if (file.fileName === '.htaccess' ||
file.fileName === '.htpasswd')
return;
file.fileName === '.htpasswd') { return; }
file.lastModified = (
new Date($($("lp1\\:getlastmodified",
xmlData).get(i)).text())).getTime();
......@@ -636,7 +649,6 @@
job.callback(res);
},
error: function (type) {
var res = {};
res.status = job.status = 'fail';
res.message = 'Cannot get list.';
res.errno = type.status;
......@@ -653,6 +665,8 @@
// returns {'status':string,'message':string,'isRemoved':boolean}
// in the jobendcallback arguments.
var res = {};
$.ajax ( {
url: job.storage.location + '/dav/' +
job.storage.userName + '/' +
......@@ -665,7 +679,6 @@
job.storage.password )},
// xhrFields: {withCredentials: 'true'}, // cross domain
success: function () {
var res = {};
res.status = job.status = 'done';
res.message = 'Document removed.';
res.isRemoved = true;
......@@ -673,7 +686,6 @@
job.callback(res);
},
error: function (type) {
var res = {};
switch (type.status) {
case 404:
res.stauts = job.status = 'done';
......@@ -693,62 +705,98 @@
}
} );
}
};
// add key to storageObject
Jio.addStorageType('dav', function (options) {
return new DAVStorage(options);
});
},
// end DAVStorage
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// ReplicateStorage
var ReplicateStorage = function ( options ) {
ReplicateStorage = function ( options ) {
this.queue = options.queue;
this.id = null;
this.length = options.storage.list.length;
this.length = options.storage.storageArray.length;
this.returnsValuesArray = [];
};
ReplicateStorage.prototype = {
checkNameAvailability: function ( job, jobendcallback ) {
var t = this;
for (var i in job.storage.list) {
var newjob = $.extend({},job);
newjob.storage = job.storage.list[i];
// Checks the availability of the [job.userName].
// if the name already exists in a storage, it is not available.
// job: the job object.
// job.userName: the name we want to check.
// job.storage.storageArray: An Array of storages.
// jobendcallback: the function called at the end of the job.
// returns {'status':string,'message':string,'isAvailable':boolean,
// 'resultArray':Array} in the jobendcallback arguments.
var t = this, newjob = {}, isavailable = true,
res = {'status':'done'}, i = 'ind';
for (i in job.storage.storageArray) {
newjob = $.extend({},job);
newjob.storage = job.storage.storageArray[i];
newjob.callback = function (result){
t.returnsValuesArray.push(result);
if (result.status === 'fail') {
res.status = 'fail';
}
if (!result.isAvailable) { isavailable = false; }
if (t.returnsValuesArray.length === t.length) {
// if this is the last callback
job.status = res.status;
res.resultArray = t.returnsValuesArray;
res.isAvailable = isavailable;
jobendcallback(job);
job.callback(res);
}
};
this.queue.addJob( newjob );
this.queue.createJob ( newjob );
}
//// callback listener
this.id = setInterval(function() {
if (t.returnsValuesArray.length >= t.length) {
var res = {};
// TODO
jobendcallback(job);
job.callback(res);
clearInterval(t.id);
}
},100);
//// end call back listener
},
saveDocument: function ( job, jobendcallback ) {
// Save a single document in several storages.
// If a storage failed to save the document, it modify the job in
// in order to invoke it sometime later.
// job: the job object
// job.options: the save options object
// job.options.overwrite: true -> overwrite
// job.options.force: true -> save even if jobdate < existingdate
// or overwrite: false
// jobendcallback: the function called at the end of the job.
// returns {'status':string,'message':string,'isSaved':boolean,
// 'resultArray':Array} in the jobendcallback arguments.
// TODO
},
loadDocument: function ( job, jobendcallback ) {
// TODO
},
getDocumentList: function ( job, jobendcallback ) {
// TODO
},
removeDocument: function ( job, jobendcallback ) {
// TODO
}
};
// end ReplicateStorage
////////////////////////////////////////////////////////////////////////////
// add key to storageObjectType of global jio
Jio.addStorageType('local', function (options) {
return new LocalStorage(options);
});
// add key to storageObject
Jio.addStorageType('dav', function (options) {
return new DAVStorage(options);
});
// add key to storageObject
Jio.addStorageType('replicate', function (options) {
return new ReplicateStorage(options);
});
// end ReplicateStorage
////////////////////////////////////////////////////////////////////////////
})( JIO );
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