Commit 38cde22c authored by Tristan Cavelier's avatar Tristan Cavelier

Separate `classes' from `singletons'.

parent 4e099262
......@@ -17,11 +17,9 @@ module.exports = function(grunt) {
// Wrapper top
'<file_strip_banner:../../src/<%= pkg.name %>/intro.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/exceptions.js>',
// Jio wrapper top
'<file_strip_banner:../../src/<%= pkg.name %>/storages/storage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/storages/storageHandler.js>',
// Jio wrapper top
'<file_strip_banner:../../src/<%= pkg.name %>/jio.intro.js>',
// Jio Classes
'<file_strip_banner:../../src/<%= pkg.name %>/commands/command.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/getDocumentList.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/commands/loadDocument.js>',
......@@ -35,6 +33,7 @@ module.exports = function(grunt) {
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/status/waitStatus.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jobs/job.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/announcements/announcement.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/jio.intro.js>',
// Singletons
'<file_strip_banner:../../src/<%= pkg.name %>/activityUpdater.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/announcements/announcer.js>',
......
......@@ -15,7 +15,9 @@ module.exports = function(grunt) {
dist: {
src: ['<banner:meta.banner>',
'<file_strip_banner:../../src/<%= pkg.name %>/intro.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/localStorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/localstorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/davstorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/replicatestorage.js>',
'<file_strip_banner:../../src/<%= pkg.name %>/outro.js>'],
dest: '../../lib/jio/<%= pkg.name %>.js'
}
......
/*! JIO - v0.1.0 - 2012-06-13
/*! JIO - v0.1.0 - 2012-06-14
* Copyright (c) 2012 Nexedi; Licensed */
var jio = (function () {
......@@ -75,7 +75,6 @@ var storage = function(spec, my) {
// Attributes //
var priv = {};
priv.type = spec.type || '';
// my.jio exists
// Methods //
that.getType = function() {
......@@ -92,6 +91,8 @@ var storage = function(spec, my) {
*/
that.execute = function(command) {
that.validate(command);
that.done = command.done;
that.fail = command.fail;
command.executeOn(that);
};
......@@ -138,67 +139,24 @@ var storage = function(spec, my) {
return '';
};
that.done = function() {};
that.fail = function() {};
return that;
};
var storageHandler = function(spec, my) {
var that = storage(spec, my);
spec = spec || {};
my = my || {};
// Attributes //
var priv = {};
priv.storage_a = spec.storagelist || [];
// Methods //
/**
* It is called before the execution.
* Override this function.
* @method beforeExecute
* @param {object} command The command.
*/
that.beforeExecute = function(command) {};
/**
* Execute the command according to this storage.
* @method execute
* @param {object} command The command.
*/
that.execute = function(command) {
var i;
that.validate(command);
that.beforeExecute(command);
for(i = 0; i < priv.storage_a.length; i++) {
priv.storage_a[i].execute(command);
}
that.afterExecute(command);
};
var that = storage( spec, my );
/**
* Is is called after the execution.
* Override this function.
* @method afterExecute
* @param {object} command The command.
*/
that.afterExecute = function(command) {
command.done();
};
/**
* Returns a serialized version of this storage
* @method serialized
* @return {object} The serialized storage.
*/
that.serialized = function() {
return {type:priv.type,
storagelist:priv.storagelist};
that.addJob = function (storage,command) {
my.jobManager.addJob ( job({storage:storage, command:command}), my );
};
return that;
};
var jio = function(spec, my) {
var command = function(spec, my) {
var that = {};
spec = spec || {};
......@@ -304,8 +262,8 @@ var command = function(spec, my) {
};
that.done = function(return_value) {
priv.done(return_value);
priv.respond({status:doneStatus(),value:return_value});
priv.done(return_value);
priv.end();
};
......@@ -313,17 +271,29 @@ var command = function(spec, my) {
if (priv.option.max_retry === 0 || priv.tried < priv.option.max_retry) {
priv.retry();
} else {
priv.fail(return_error);
priv.respond({status:failStatus(),error:return_error});
priv.fail(return_error);
priv.end();
}
};
that.onEndDo = function(fun) {
that.onResponseDo = function (fun) {
priv.respond = fun;
};
that.onDoneDo = function (fun) {
priv.done = fun;
};
that.onFailDo = function (fun) {
priv.fail = fun;
};
that.onEndDo = function (fun) {
priv.end = fun;
};
that.onRetryDo = function(fun) {
that.onRetryDo = function (fun) {
priv.retry = fun;
};
......@@ -345,6 +315,10 @@ var command = function(spec, my) {
return true;
};
that.clone = function () {
return command(that.serialized(), my);
};
return that;
};
......@@ -366,6 +340,24 @@ var getDocumentList = function(spec, my) {
return false;
};
var super_done = that.done;
that.done = function (res) {
var i;
if (res) {
for (i = 0; i < res.length; i+= 1) {
if (typeof res[i].last_modified !== 'number') {
res[i].last_modified =
new Date(res[i].last_modified).getTime();
}
if (typeof res[i].creation_date !== 'number') {
res[i].creation_date =
new Date(res[i].creation_date).getTime();
}
}
}
super_done(res);
};
return that;
};
......@@ -387,6 +379,18 @@ var loadDocument = function(spec, my) {
return false;
};
var super_done = that.done;
that.done = function (res) {
if (res) {
if (typeof res.last_modified !== 'number') {
res.last_modified=new Date(res.last_modified).getTime();
}
if (typeof res.creation_date !== 'number') {
res.creation_date=new Date(res.creation_date).getTime();
}
}
super_done(res);
};
return that;
};
......@@ -465,8 +469,14 @@ var jobStatus = function(spec, my) {
that.serialized = function() {
return {label:that.getLabel()};
};
that.isWaitStatus = function() {
return false;
};
return that;
};
var doneStatus = function(spec, my) {
var that = jobStatus(spec, my);
spec = spec || {};
......@@ -549,21 +559,36 @@ var waitStatus = function(spec, my) {
var priv = {};
priv.job_id_a = spec.job_id_array || [];
priv.threshold = 0;
// Methods //
/**
* Returns the label of this status.
* @method getLabel
* @return {string} The label: 'wait'.
*/
that.getLabel = function() {
return 'wait';
};
/**
* Refresh the job id array to wait.
* @method refreshJobIdArray
*/
priv.refreshJobIdArray = function() {
var tmp_job_id_a = [], i;
for (i = 0; i < priv.job_id_a.length; i+= 1) {
if (jobManager.jobIdExists(priv.job_id_a[i])) {
if (my.jobManager.jobIdExists(priv.job_id_a[i])) {
tmp_job_id_a.push(priv.job_id_a[i]);
}
}
priv.job_id_a = tmp_job_id_a;
};
/**
* The status must wait for the job end before start again.
* @method waitForJob
* @param {object} job The job to wait for.
*/
that.waitForJob = function(job) {
var i;
for (i = 0; i < priv.job_id_a.length; i+= 1) {
......@@ -573,6 +598,12 @@ var waitStatus = function(spec, my) {
}
priv.job_id_a.push(job.getId());
};
/**
* The status stops to wait for this job.
* @method dontWaitForJob
* @param {object} job The job to stop waiting for.
*/
that.dontWaitForJob = function(job) {
var i, tmp_job_id_a = [];
for (i = 0; i < priv.job_id_a.length; i+= 1) {
......@@ -583,9 +614,19 @@ var waitStatus = function(spec, my) {
priv.job_id_a = tmp_job_id_a;
};
/**
* The status must wait for some milliseconds.
* @method waitForTime
* @param {number} ms The number of milliseconds
*/
that.waitForTime = function(ms) {
priv.threshold = Date.now() + ms;
};
/**
* The status stops to wait for some time.
* @method stopWaitForTime
*/
that.stopWaitForTime = function() {
priv.threshold = 0;
};
......@@ -604,6 +645,15 @@ var waitStatus = function(spec, my) {
waitforjob:priv.job_id_a};
};
/**
* Checks if this status is waitStatus
* @method isWaitStatus
* @return {boolean} true
*/
that.isWaitStatus = function () {
return true;
};
return that;
};
......@@ -613,7 +663,7 @@ var job = function(spec, my) {
my = my || {};
// Attributes //
var priv = {};
priv.id = jobIdHandler.nextId();
priv.id = my.jobIdHandler.nextId();
priv.command = spec.command;
priv.storage = spec.storage;
priv.status = initialStatus();
......@@ -687,7 +737,7 @@ var job = function(spec, my) {
*/
that.waitForJob = function(job) {
if (priv.status.getLabel() !== 'wait') {
priv.status = waitStatus();
priv.status = waitStatus({},my);
}
priv.status.waitForJob(job);
};
......@@ -710,7 +760,7 @@ var job = function(spec, my) {
*/
that.waitForTime = function(ms) {
if (priv.status.getLabel() !== 'wait') {
priv.status = waitStatus();
priv.status = waitStatus({},my);
}
priv.status.waitForTime(ms);
};
......@@ -757,7 +807,7 @@ var job = function(spec, my) {
that.waitForTime(ms);
});
priv.command.onEndDo (function() {
jobManager.terminateJob (that);
my.jobManager.terminateJob (that);
});
priv.command.execute (priv.storage);
};
......@@ -772,6 +822,7 @@ var announcement = function(spec, my) {
// Attributes //
var callback_a = [];
var name = spec.name || '';
var announcer = spec.announcer || {};
// Methods //
that.add = function(callback) {
callback_a.push(callback);
......@@ -805,6 +856,9 @@ var announcement = function(spec, my) {
return that;
};
var jio = function(spec, my) {
var activityUpdater = (function(spec, my) {
var that = {};
spec = spec || {};
......@@ -814,19 +868,49 @@ var activityUpdater = (function(spec, my) {
priv.id = spec.id || 0;
priv.interval = 400;
priv.interval_id = null;
// Methods //
/**
* Update the last activity date in the localStorage.
* @method touch
*/
priv.touch = function() {
LocalOrCookieStorage.setItem ('jio/id/'+priv.id, Date.now());
};
/**
* Sets the jio id into the activity.
* @method setId
* @param {number} id The jio id.
*/
that.setId = function(id) {
priv.id = id;
};
/**
* Sets the interval delay between two updates.
* @method setIntervalDelay
* @param {number} ms In milliseconds
*/
that.setIntervalDelay = function(ms) {
priv.interval = ms;
};
/**
* Gets the interval delay.
* @method getIntervalDelay
* @return {number} The interval delay.
*/
that.getIntervalDelay = function() {
return priv.interval;
};
/**
* Starts the activity updater. It will update regulary the last activity
* date in the localStorage to show to other jio instance that this instance
* is active.
* @method start
*/
that.start = function() {
if (!priv.interval_id) {
priv.touch();
......@@ -835,12 +919,18 @@ var activityUpdater = (function(spec, my) {
}, priv.interval);
}
};
/**
* Stops the activity updater.
* @method stop
*/
that.stop = function() {
if (priv.interval_id !== null) {
clearInterval(priv.interval_id);
priv.interval_id = null;
}
};
return that;
}());
......@@ -907,13 +997,32 @@ var jobManager = (function(spec, my) {
priv.interval = 200;
priv.job_a = [];
my.jobManager = that;
my.jobIdHandler = that;
// Methods //
/**
* Get the job array name in the localStorage
* @method getJobArrayName
* @return {string} The job array name
*/
priv.getJobArrayName = function() {
return job_array_name + '/' + priv.id;
};
/**
* Returns the job array from the localStorage
* @method getJobArray
* @return {array} The job array.
*/
priv.getJobArray = function() {
return LocalOrCookieStorage.getItem(priv.getJobArrayName())||[];
};
/**
* Does a backup of the job array in the localStorage.
* @method copyJobArrayToLocal
*/
priv.copyJobArrayToLocal = function() {
var new_a = [], i;
for (i = 0; i < priv.job_a.length; i+= 1) {
......@@ -922,6 +1031,11 @@ var jobManager = (function(spec, my) {
LocalOrCookieStorage.setItem(priv.getJobArrayName(),new_a);
};
/**
* Removes a job from the current job array.
* @method removeJob
* @param {object} job The job object.
*/
priv.removeJob = function(job) {
var i, tmp_job_a = [];
for (i = 0; i < priv.job_a.length; i+= 1) {
......@@ -972,6 +1086,12 @@ var jobManager = (function(spec, my) {
}
};
/**
* Try to restore an the inactive older jio instances.
* It will restore the on going or initial jobs from their job array
* and it will add them to this job array.
* @method restoreOldJio
*/
priv.restoreOldJio = function() {
var i, jio_id_a;
priv.lastrestore = priv.lastrestore || 0;
......@@ -983,6 +1103,11 @@ var jobManager = (function(spec, my) {
priv.lastrestore = Date.now();
};
/**
* Try to restore an old jio according to an id.
* @method restoreOldJioId
* @param {number} id The jio id.
*/
priv.restoreOldJioId = function(id) {
var jio_date;
jio_date = LocalOrCookieStorage.getItem('jio/id/'+id)||0;
......@@ -993,19 +1118,29 @@ var jobManager = (function(spec, my) {
}
};
/**
* Try to restore all jobs from another jio according to an id.
* @method restoreOldJobFromJioId
* @param {number} id The jio id.
*/
priv.restoreOldJobFromJioId = function(id) {
var i, jio_job_array;
jio_job_array = LocalOrCookieStorage.getItem('jio/job_array/'+id)||[];
for (i = 0; i < jio_job_array.length; i+= 1) {
var command_o = command(jio_job_array[i].command);
var command_o = command(jio_job_array[i].command, my);
if (command_o.canBeRestored()) {
that.addJob ( job(
{storage:jioNamespace.storage(jio_job_array[i].storage),
command:command_o}));
{storage:jioNamespace.storage(jio_job_array[i].storage,my),
command:command_o}, my));
}
}
};
/**
* Removes a jio instance according to an id.
* @method removeOldJioId
* @param {number} id The jio id.
*/
priv.removeOldJioId = function(id) {
var i, jio_id_a, new_a = [];
jio_id_a = LocalOrCookieStorage.getItem('jio/id_array')||[];
......@@ -1018,6 +1153,11 @@ var jobManager = (function(spec, my) {
LocalOrCookieStorage.deleteItem('jio/id/'+id);
};
/**
* Removes a job array from a jio instance according to an id.
* @method removeJobArrayFromJioId
* @param {number} id The jio id.
*/
priv.removeJobArrayFromJioId = function(id) {
LocalOrCookieStorage.deleteItem('jio/job_array/'+id);
};
......@@ -1040,6 +1180,12 @@ var jobManager = (function(spec, my) {
priv.copyJobArrayToLocal();
};
/**
* Checks if a job exists in the job array according to a job id.
* @method jobIdExists
* @param {number} id The job id.
* @return {boolean} true if exists, else false.
*/
that.jobIdExists = function(id) {
var i;
for (i = 0; i < priv.job_a.length; i+= 1) {
......@@ -1050,16 +1196,32 @@ var jobManager = (function(spec, my) {
return false;
};
/**
* Terminate a job. It only remove it from the job array.
* @method terminateJob
* @param {object} job The job object
*/
that.terminateJob = function(job) {
priv.removeJob(job);
priv.copyJobArrayToLocal();
};
/**
* Adds a job to the current job array.
* @method addJob
* @param {object} job The new job.
*/
that.addJob = function(job) {
var result_a = that.validateJobAccordingToJobList (priv.job_a,job);
priv.manage (job,result_a);
priv.appendJob (job,result_a);
};
/**
* Generate a result array containing action string to do with the good job.
* @method validateJobAccordingToJobList
* @param {array} job_a A job array.
* @param {object} job The new job to compare with.
* @return {array} A result array.
*/
that.validateJobAccordingToJobList = function(job_a,job) {
var i, result_a = [];
for (i = 0; i < job_a.length; i+= 1) {
......@@ -1068,7 +1230,16 @@ var jobManager = (function(spec, my) {
return result_a;
};
priv.manage = function(job,result_a) {
/**
* It will manage the job in order to know what to do thanks to a result
* array. The new job can be added to the job array, but it can also be
* not accepted. It is this method which can tells jobs to wait for another
* one, to replace one or to eliminate some while browsing.
* @method appendJob
* @param {object} job The job to append.
* @param {array} result_a The result array.
*/
priv.appendJob = function(job,result_a) {
var i;
if (priv.job_a.length !== result_a.length) {
throw new RangeError("Array out of bound");
......@@ -1081,7 +1252,7 @@ var jobManager = (function(spec, my) {
for (i = 0; i < result_a.length; i+= 1) {
switch (result_a[i].action) {
case 'eliminate':
that.eliminate(result_a[i].job);
priv.removeJob(result_a[i].job);
break;
case 'update':
result_a[i].job.update(job);
......@@ -1097,17 +1268,6 @@ var jobManager = (function(spec, my) {
priv.copyJobArrayToLocal();
};
that.eliminate = function(job) {
var i, tmp_a = [];
for (i = 0; i < priv.job_a.length; i+= 1) {
if (priv.job_a[i].getId() !== job.getId()) {
tmp_a.push(priv.job_a[i]);
}
}
priv.job_a = tmp_a;
priv.copyJobArrayToLocal();
};
return that;
}());
......@@ -1131,6 +1291,13 @@ var jobRules = (function(spec, my) {
};
// Methods //
/**
* Returns an action according the jobs given in parameters.
* @method getAction
* @param {object} job1 The already existant job.
* @param {object} job2 The job to compare with.
* @return {string} An action string.
*/
priv.getAction = function(job1,job2) {
var j1label, j2label, j1status;
j1label = job1.getCommand().getLabel();
......@@ -1145,6 +1312,14 @@ var jobRules = (function(spec, my) {
return that.default_action(job1,job2);
}
};
/**
* Checks if the two jobs are comparable.
* @method canCompare
* @param {object} job1 The already existant job.
* @param {object} job2 The job to compare with.
* @return {boolean} true if comparable, else false.
*/
priv.canCompare = function(job1,job2) {
var job1label = job1.getCommand().getLabel(),
job2label = job2.getCommand().getLabel();
......@@ -1198,6 +1373,8 @@ var jobRules = (function(spec, my) {
priv.compare[method1][method2] = rule;
};
////////////////////////////////////////////////////////////////////////////
// Adding some rules
/*
LEGEND:
- s: storage
......@@ -1278,6 +1455,8 @@ var jobRules = (function(spec, my) {
that.addActionRule('getDocumentList',true ,'getDocumentList',that.dontAccept);
that.addActionRule('getDocumentList',false,'getDocumentList',that.update);
// end adding rules
////////////////////////////////////////////////////////////////////////////
return that;
}());
......@@ -1289,7 +1468,11 @@ var jobRules = (function(spec, my) {
var priv = {};
var jio_id_array_name = 'jio/id_array';
priv.id = null;
priv.storage = jioNamespace.storage(spec);
my.jobManager = jobManager;
my.jobIdHandler = jobIdHandler;
priv.storage = jioNamespace.storage(spec, my);
// initialize //
priv.init = function() {
......@@ -1351,7 +1534,7 @@ var jobRules = (function(spec, my) {
* @return {boolean} true if ok, else false.
*/
that.validateStorageDescription = function(description) {
return jioNamespace.storage(description.type)(description).isValid();
return jioNamespace.storage(description, my).isValid();
};
/**
......@@ -1375,10 +1558,10 @@ var jobRules = (function(spec, my) {
option.max_retry = option.max_retry || 0;
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:saveDocument(
{path:path,content:content,option:option})}));
{path:path,content:content,option:option})},my));
};
/**
......@@ -1404,10 +1587,10 @@ var jobRules = (function(spec, my) {
option.metadata_only:false);
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:loadDocument(
{path:path,option:option})}));
{path:path,option:option})},my));
};
/**
......@@ -1430,10 +1613,10 @@ var jobRules = (function(spec, my) {
option.max_retry = option.max_retry || 0;
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:removeDocument(
{path:path,option:option})}));
{path:path,option:option})},my));
};
/**
......@@ -1459,10 +1642,10 @@ var jobRules = (function(spec, my) {
option.metadata_only:true);
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:getDocumentList(
{path:path,option:option})}));
{path:path,option:option})},my));
};
return that;
......@@ -1473,7 +1656,10 @@ var jioNamespace = (function(spec, my) {
spec = spec || {};
my = my || {};
// Attributes //
var storage_type_o = {'base':storage,'handler':storageHandler};
var storage_type_o = { // -> 'key':constructorFunction
'base': storage,
'handler': storageHandler
};
// Methods //
......
/*! JIO - v0.1.0 - 2012-06-13
/*! JIO - v0.1.0 - 2012-06-14
* Copyright (c) 2012 Nexedi; Licensed */
var jio=function(){var a=function(a,b){var c={};return a=a||{},b=b||{},c.name="jioException",c.message=a.message||"Unknown Reason.",c.toString=function(){return c.name+": "+c.message},c},b=function(b,c){var d=a(b,c);b=b||{};var e=b.command;return d.name="invalidCommandState",d.toString=function(){return d.name+": "+e.getLabel()+", "+d.message},d},c=function(b,c){var d=a(b,c);b=b||{};var e=b.storage.getType();return d.name="invalidStorage",d.toString=function(){return d.name+": "+'Type "'+e+'", '+d.message},d},d=function(b,c){var d=a(b,c),e=b.type;return d.name="invalidStorageType",d.toString=function(){return d.name+": "+e+", "+d.message},d},e=function(b,c){var d=a(b,c);return d.name="jobNotReadyException",d},f=function(b,c){var d=a(b,c);return d.name="tooMuchTriesJobException",d},g=function(b,c){var d=a(b,c);return d.name="invalidJobException",d},h=function(a,b){var d={};a=a||{},b=b||{};var e={};return e.type=a.type||"",d.getType=function(){return e.type},d.setType=function(a){e.type=a},d.execute=function(a){d.validate(a),a.executeOn(d)},d.isValid=function(){return!0},d.validate=function(a){var b=d.validateState();if(b)throw c({storage:d,message:b});a.validate(d)},d.serialized=function(){return{type:d.getType()}},d.saveDocument=function(a){throw c({storage:d,message:"Unknown storage."})},d.loadDocument=function(a){d.saveDocument()},d.removeDocument=function(a){d.saveDocument()},d.getDocumentList=function(a){d.saveDocument()},d.validateState=function(){return""},d},i=function(a,b){var c=h(a,b);a=a||{},b=b||{};var d={};return d.storage_a=a.storagelist||[],c.beforeExecute=function(a){},c.execute=function(a){var b;c.validate(a),c.beforeExecute(a);for(b=0;b<d.storage_a.length;b++)d.storage_a[b].execute(a);c.afterExecute(a)},c.afterExecute=function(a){a.done()},c.serialized=function(){return{type:d.type,storagelist:d.storagelist}},c},j=function(a,c){var d=function(a,c){var d={};a=a||{},c=c||{};var e={};return e.commandlist={saveDocument:l,loadDocument:i,removeDocument:j,getDocumentList:h},a.label&&e.commandlist[a.label]?(e.label=a.label,delete a.label,e.commandlist[e.label](a,c)):(e.path=a.path||"",e.tried=0,e.option=a.option||{},e.respond=e.option.onResponse||function(){},e.done=e.option.onDone||function(){},e.fail=e.option.onFail||function(){},e.retry=function(){d.setMaxRetry(-1),d.fail({status:0,statusText:"Fail Retry",message:"Impossible to retry."})},e.end=function(){},d.getLabel=function(){return"command"},d.getPath=function(){return e.path},d.getOption=function(a){return e.option[a]},d.validate=function(a){d.validateState()},d.getTried=function(){return e.tried},d.setMaxRetry=function(a){e.option.max_retry=a},d.execute=function(a){d.validate(a),e.tried++,a.execute(d)},d.executeOn=function(a){},d.validateState=function(){if(e.path==="")throw b({command:d,message:"Path is empty"})},d.done=function(a){e.done(a),e.respond({status:n(),value:a}),e.end()},d.fail=function(a){e.option.max_retry===0||e.tried<e.option.max_retry?e.retry():(e.fail(a),e.respond({status:o(),error:a}),e.end())},d.onEndDo=function(a){e.end=a},d.onRetryDo=function(a){e.retry=a},d.serialized=function(){return{label:d.getLabel(),tried:e.tried,max_retry:e.max_retry,path:e.path,option:e.option}},d.canBeRestored=function(){return!0},d)},h=function(a,b){var c=d(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"getDocumentList"},c.executeOn=function(a){a.getDocumentList(c)},c.canBeRestored=function(){return!1},c},i=function(a,b){var c=d(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"loadDocument"},c.executeOn=function(a){a.loadDocument(c)},c.canBeRestored=function(){return!1},c},j=function(a,b){var c=d(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"removeDocument"},c.executeOn=function(a){a.removeDocument(c)},c},l=function(a,c){var e=d(a,c);a=a||{},c=c||{};var f={};f.content=a.content,e.getLabel=function(){return"saveDocument"},e.getContent=function(){return f.content};var g=e.validate;e.validate=function(a){if(typeof f.content!="string")throw b({command:e,message:"No data to save"});g(a)},e.executeOn=function(a){a.saveDocument(e)};var h=e.serialized;return e.serialized=function(){var a=h();return a.content=f.content,a},e},m=function(a,b){var c={};return a=a||{},b=b||{},c.getLabel=function(){return"job status"},c.canStart=function(){},c.canRestart=function(){},c.serialized=function(){return{label:c.getLabel()}},c},n=function(a,b){var c=m(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"done"},c.canStart=function(){return!1},c.canRestart=function(){return!1},c},o=function(a,b){var c=m(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"fail"},c.canStart=function(){return!1},c.canRestart=function(){return!0},c},p=function(a,b){var c=m(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"initial"},c.canStart=function(){return!0},c.canRestart=function(){return!0},c},q=function(a,b){var c=m(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"on going"},c.canStart=function(){return!1},c.canRestart=function(){return!1},c},r=function(a,b){var c=m(a,b);a=a||{},b=b||{};var d={};return d.job_id_a=a.job_id_array||[],d.threshold=0,c.getLabel=function(){return"wait"},d.refreshJobIdArray=function(){var a=[],b;for(b=0;b<d.job_id_a.length;b+=1)x.jobIdExists(d.job_id_a[b])&&a.push(d.job_id_a[b]);d.job_id_a=a},c.waitForJob=function(a){var b;for(b=0;b<d.job_id_a.length;b+=1)if(d.job_id_a[b]===a.getId())return;d.job_id_a.push(a.getId())},c.dontWaitForJob=function(a){var b,c=[];for(b=0;b<d.job_id_a.length;b+=1)d.job_id_a[b]!==a.getId()&&c.push(d.job_id_a[b]);d.job_id_a=c},c.waitForTime=function(a){d.threshold=Date.now()+a},c.stopWaitForTime=function(){d.threshold=0},c.canStart=function(){return d.refreshJobIdArray(),d.job_id_a.length===0&&Date.now()>=d.threshold},c.canRestart=function(){return c.canStart()},c.serialized=function(){return{label:c.getLabel(),waitfortime:d.threshold,waitforjob:d.job_id_a}},c},s=function(a,b){var c={};a=a||{},b=b||{};var d={};return d.id=w.nextId(),d.command=a.command,d.storage=a.storage,d.status=p(),d.date=new Date,function(){if(!d.storage)throw g({job:c,message:"No storage set"});if(!d.command)throw g({job:c,message:"No command set"})}(),c.getCommand=function(){return d.command},c.getStatus=function(){return d.status},c.getId=function(){return d.id},c.getStorage=function(){return d.storage},c.getDate=function(){return d.date},c.isReady=function(){return d.tried===0?d.status.canStart():d.status.canRestart()},c.serialized=function(){return{id:d.id,date:d.date.getTime(),status:d.status.serialized(),command:d.command.serialized(),storage:d.storage.serialized()}},c.waitForJob=function(a){d.status.getLabel()!=="wait"&&(d.status=r()),d.status.waitForJob(a)},c.dontWaitFor=function(a){d.status.getLabel()==="wait"&&d.status.dontWaitForJob(a)},c.waitForTime=function(a){d.status.getLabel()!=="wait"&&(d.status=r()),d.status.waitForTime(a)},c.stopWaitForTime=function(){d.status.getLabel()==="wait"&&d.status.stopWaitForTime()},c.update=function(a){d.command.setMaxRetry(-1),d.command.fail({status:0,statusText:"Replaced",message:"Job has been replaced by another one."}),d.date=a.getDate(),d.command=a.getCommand(),d.status=a.getStatus()},c.execute=function(){if(d.max_retry!==0&&d.tried>=d.max_retry)throw f({job:c,message:"The job was invoked too much time."});if(!c.isReady())throw e({message:"Can not execute this job."});d.status=q(),d.command.onRetryDo(function(){var a=d.command.getTried();a=a*a*200,a>1e4&&(a=1e4),c.waitForTime(a)}),d.command.onEndDo(function(){x.terminateJob(c)}),d.command.execute(d.storage)},c},t=function(a,b){var c={};a=a||{},b=b||{};var d=[],e=a.name||"";return c.add=function(a){d.push(a)},c.remove=function(a){var b,c=[];for(b=0;b<d.length;b+=1)d[b]!==a&&c.push(d[b]);d=c},c.register=function(){v.register(c)},c.unregister=function(){v.unregister(c)},c.trigger=function(a){var b;for(b=0;b<d.length;b++)d[b].apply(null,a)},c},u=function(a,b){var c={};a=a||{},b=b||{};var d={};return d.id=a.id||0,d.interval=400,d.interval_id=null,d.touch=function(){LocalOrCookieStorage.setItem("jio/id/"+d.id,Date.now())},c.setId=function(a){d.id=a},c.setIntervalDelay=function(a){d.interval=a},c.getIntervalDelay=function(){return d.interval},c.start=function(){d.interval_id||(d.touch(),d.interval_id=setInterval(function(){d.touch()},d.interval))},c.stop=function(){d.interval_id!==null&&(clearInterval(d.interval_id),d.interval_id=null)},c}(),v=function(a,b){var c={};a=a||{},b=b||{};var d={};return c.register=function(a){d[a]||(d[a]=t())},c.unregister=function(a){d[a]&&delete d[a]},c.at=function(a){return d[a]},c.on=function(a,b){c.register(a),c.at(a).add(b)},c.trigger=function(a,b){c.at(a).trigger(b)},c}(),w=function(a,b){var c={};a=a||{},b=b||{};var d=0;return c.nextId=function(){return d=d+1,d},c}(),x=function(a,b){var c={};a=a||{},b=b||{};var e="jio/job_array",f={};return f.id=a.id,f.interval_id=null,f.interval=200,f.job_a=[],f.getJobArrayName=function(){return e+"/"+f.id},f.getJobArray=function(){return LocalOrCookieStorage.getItem(f.getJobArrayName())||[]},f.copyJobArrayToLocal=function(){var a=[],b;for(b=0;b<f.job_a.length;b+=1)a.push(f.job_a[b].serialized());LocalOrCookieStorage.setItem(f.getJobArrayName(),a)},f.removeJob=function(a){var b,c=[];for(b=0;b<f.job_a.length;b+=1)f.job_a[b]!==a&&c.push(f.job_a[b]);f.job_a=c,f.copyJobArrayToLocal()},c.setId=function(a){f.id=a},c.start=function(){var a;f.interval_id===null&&(f.interval_id=setInterval(function(){f.restoreOldJio();for(a=0;a<f.job_a.length;a+=1)c.execute(f.job_a[a])},f.interval))},c.stop=function(){f.interval_id!==null&&(clearInterval(f.interval_id),f.interval_id=null,f.job_a.length===0&&LocalOrCookieStorage.deleteItem(f.getJobArrayName()))},f.restoreOldJio=function(){var a,b;f.lastrestore=f.lastrestore||0;if(f.lastrestore>Date.now()-2e3)return;b=LocalOrCookieStorage.getItem("jio/id_array")||[];for(a=0;a<b.length;a+=1)f.restoreOldJioId(b[a]);f.lastrestore=Date.now()},f.restoreOldJioId=function(a){var b;b=LocalOrCookieStorage.getItem("jio/id/"+a)||0,b<Date.now()-1e4&&(f.restoreOldJobFromJioId(a),f.removeOldJioId(a),f.removeJobArrayFromJioId(a))},f.restoreOldJobFromJioId=function(a){var b,e;e=LocalOrCookieStorage.getItem("jio/job_array/"+a)||[];for(b=0;b<e.length;b+=1){var f=d(e[b].command);f.canBeRestored()&&c.addJob(s({storage:k.storage(e[b].storage),command:f}))}},f.removeOldJioId=function(a){var b,c,d=[];c=LocalOrCookieStorage.getItem("jio/id_array")||[];for(b=0;b<c.length;b+=1)c[b]!==a&&d.push(c[b]);LocalOrCookieStorage.setItem("jio/id_array",d),LocalOrCookieStorage.deleteItem("jio/id/"+a)},f.removeJobArrayFromJioId=function(a){LocalOrCookieStorage.deleteItem("jio/job_array/"+a)},c.execute=function(a){try{a.execute()}catch(b){switch(b.name){case"jobNotReadyException":break;case"tooMuchTriesJobException":break;default:throw b}}f.copyJobArrayToLocal()},c.jobIdExists=function(a){var b;for(b=0;b<f.job_a.length;b+=1)if(f.job_a[b].getId()===a)return!0;return!1},c.terminateJob=function(a){f.removeJob(a),f.copyJobArrayToLocal()},c.addJob=function(a){var b=c.validateJobAccordingToJobList(f.job_a,a);f.manage(a,b)},c.validateJobAccordingToJobList=function(a,b){var c,d=[];for(c=0;c<a.length;c+=1)d.push(y.validateJobAccordingToJob(a[c],b));return d},f.manage=function(a,b){var d;if(f.job_a.length!==b.length)throw new RangeError("Array out of bound");for(d=0;d<b.length;d+=1)if(b[d].action==="dont accept")return;for(d=0;d<b.length;d+=1)switch(b[d].action){case"eliminate":c.eliminate(b[d].job);break;case"update":b[d].job.update(a),f.copyJobArrayToLocal();return;case"wait":a.waitForJob(b[d].job);break;default:}f.job_a.push(a),f.copyJobArrayToLocal()},c.eliminate=function(a){var b,c=[];for(b=0;b<f.job_a.length;b+=1)f.job_a[b].getId()!==a.getId()&&c.push(f.job_a[b]);f.job_a=c,f.copyJobArrayToLocal()},c}(),y=function(a,b){var c={},d={};return d.compare={},d.action={},c.eliminate=function(){return"eliminate"},c.update=function(){return"update"},c.dontAccept=function(){return"dont accept"},c.wait=function(){return"wait"},c.none=function(){return"none"},c.default_action=c.none,c.default_compare=function(a,b){return a.getCommand().getPath()===b.getCommand().getPath()&&JSON.stringify(a.getStorage().serialized())===JSON.stringify(b.getStorage().serialized())},d.getAction=function(a,b){var e,f,g;return e=a.getCommand().getLabel(),f=b.getCommand().getLabel(),g=a.getStatus().getLabel()==="on going"?"on going":"not on going",d.action[e]&&d.action[e][g]&&d.action[e][g][f]?d.action[e][g][f](a,b):c.default_action(a,b)},d.canCompare=function(a,b){var e=a.getCommand().getLabel(),f=b.getCommand().getLabel();return d.compare[e]&&d.compare[f]?d.compare[e][f](a,b):c.default_compare(a,b)},c.validateJobAccordingToJob=function(a,b){return d.canCompare(a,b)?{action:d.getAction(a,b),job:a}:{action:c.default_action(a,b),job:a}},c.addActionRule=function(a,b,c,e){var f=b?"on going":"not on going";d.action[a]=d.action[a]||{},d.action[a][f]=d.action[a][f]||{},d.action[a][f][c]=e},c.addCompareRule=function(a,b,c){d.compare[a]=d.compare[a]||{},d.compare[a][b]=c},c.addActionRule("saveDocument",!0,"saveDocument",function(a,b){return a.getCommand().getContent()===b.getCommand().getContent()?c.dontAccept():c.wait()}),c.addActionRule("saveDocument",!0,"loadDocument",c.wait),c.addActionRule("saveDocument",!0,"removeDocument",c.wait),c.addActionRule("saveDocument",!1,"saveDocument",c.update),c.addActionRule("saveDocument",!1,"loadDocument",c.wait),c.addActionRule("saveDocument",!1,"removeDocument",c.eliminate),c.addActionRule("loadDocument",!0,"saveDocument",c.wait),c.addActionRule("loadDocument",!0,"loadDocument",c.dontAccept),c.addActionRule("loadDocument",!0,"removeDocument",c.wait),c.addActionRule("loadDocument",!1,"saveDocument",c.wait),c.addActionRule("loadDocument",!1,"loadDocument",c.update),c.addActionRule("loadDocument",!1,"removeDocument",c.wait),c.addActionRule("removeDocument",!0,"loadDocument",c.dontAccept),c.addActionRule("removeDocument",!0,"removeDocument",c.dontAccept),c.addActionRule("removeDocument",!1,"saveDocument",c.eliminate),c.addActionRule("removeDocument",!1,"loadDocument",c.dontAccept),c.addActionRule("removeDocument",!1,"removeDocument",c.update),c.addActionRule("getDocumentList",!0,"getDocumentList",c.dontAccept),c.addActionRule("getDocumentList",!1,"getDocumentList",c.update),c}(),z={};a=a||{},c=c||{};var A={},B="jio/id_array";return A.id=null,A.storage=k.storage(a),A.init=function(){if(A.id===null){var a,b=LocalOrCookieStorage.getItem(B)||[];A.id=1;for(a=0;a<b.length;a+=1)b[a]>=A.id&&(A.id=b[a]+1);b.push(A.id),LocalOrCookieStorage.setItem(B,b),u.setId(A.id),x.setId(A.id)}},z.start=function(){A.init(),u.start(),x.start()},z.stop=function(){x.stop()},z.close=function(){u.stop(),x.stop(),A.id=null},z.start(),z.getId=function(){return A.id},z.getJobRules=function(){return y},z.validateStorageDescription=function(a){return k.storage(a.type)(a).isValid()},z.saveDocument=function(a,b,c,d){c=c||{},c.onResponse=c.onResponse||function(){},c.onDone=c.onDone||function(){},c.onFail=c.onFail||function(){},c.max_retry=c.max_retry||0,x.addJob(s({storage:d?k.storage(d):A.storage,command:l({path:a,content:b,option:c})}))},z.loadDocument=function(a,b,c){b=b||{},b.onResponse=b.onResponse||function(){},b.onDone=b.onDone||function(){},b.onFail=b.onFail||function(){},b.max_retry=b.max_retry||0,b.metadata_only=b.metadata_only!==undefined?b.metadata_only:!1,x.addJob(s({storage:c?k.storage(c):A.storage,command:i({path:a,option:b})}))},z.removeDocument=function(a,b,c){b=b||{},b.onResponse=b.onResponse||function(){},b.onDone=b.onDone||function(){},b.onFail=b.onFail||function(){},b.max_retry=b.max_retry||0,x.addJob(s({storage:c?k.storage(c):A.storage,command:j({path:a,option:b})}))},z.getDocumentList=function(a,b,c){b=b||{},b.onResponse=b.onResponse||function(){},b.onDone=b.onDone||function(){},b.onFail=b.onFail||function(){},b.max_retry=b.max_retry||0,b.metadata_only=b.metadata_only!==undefined?b.metadata_only:!0,x.addJob(s({storage:c?k.storage(c):A.storage,command:h({path:a,option:b})}))},z},k=function(a,b){var c={};a=a||{},b=b||{};var e={base:h,handler:i};return c.storage=function(a,b,c){a=a||{};var f=c||a.type||"base";if(!e[f])throw d({type:f,message:"Storage does not exists."});return e[f](a,b)},c.newJio=function(a){var b=a;return typeof b=="string"&&(b=JSON.parse(b)),b=b||{type:"base"},j(a)},c.addStorageType=function(a,b){b=b||function(){return null};if(e[a])throw d({type:a,message:"Already known."});e[a]=b},c}();return k}();
\ No newline at end of file
var jio=function(){var a=function(a,b){var c={};return a=a||{},b=b||{},c.name="jioException",c.message=a.message||"Unknown Reason.",c.toString=function(){return c.name+": "+c.message},c},b=function(b,c){var d=a(b,c);b=b||{};var e=b.command;return d.name="invalidCommandState",d.toString=function(){return d.name+": "+e.getLabel()+", "+d.message},d},c=function(b,c){var d=a(b,c);b=b||{};var e=b.storage.getType();return d.name="invalidStorage",d.toString=function(){return d.name+": "+'Type "'+e+'", '+d.message},d},d=function(b,c){var d=a(b,c),e=b.type;return d.name="invalidStorageType",d.toString=function(){return d.name+": "+e+", "+d.message},d},e=function(b,c){var d=a(b,c);return d.name="jobNotReadyException",d},f=function(b,c){var d=a(b,c);return d.name="tooMuchTriesJobException",d},g=function(b,c){var d=a(b,c);return d.name="invalidJobException",d},h=function(a,b){var d={};a=a||{},b=b||{};var e={};return e.type=a.type||"",d.getType=function(){return e.type},d.setType=function(a){e.type=a},d.execute=function(a){d.validate(a),d.done=a.done,d.fail=a.fail,a.executeOn(d)},d.isValid=function(){return!0},d.validate=function(a){var b=d.validateState();if(b)throw c({storage:d,message:b});a.validate(d)},d.serialized=function(){return{type:d.getType()}},d.saveDocument=function(a){throw c({storage:d,message:"Unknown storage."})},d.loadDocument=function(a){d.saveDocument()},d.removeDocument=function(a){d.saveDocument()},d.getDocumentList=function(a){d.saveDocument()},d.validateState=function(){return""},d.done=function(){},d.fail=function(){},d},i=function(a,b){a=a||{},b=b||{};var c=h(a,b);return c.addJob=function(a,c){b.jobManager.addJob(u({storage:a,command:c}),b)},c},j=function(a,c){var d={};a=a||{},c=c||{};var e={};return e.commandlist={saveDocument:n,loadDocument:l,removeDocument:m,getDocumentList:k},a.label&&e.commandlist[a.label]?(e.label=a.label,delete a.label,e.commandlist[e.label](a,c)):(e.path=a.path||"",e.tried=0,e.option=a.option||{},e.respond=e.option.onResponse||function(){},e.done=e.option.onDone||function(){},e.fail=e.option.onFail||function(){},e.retry=function(){d.setMaxRetry(-1),d.fail({status:0,statusText:"Fail Retry",message:"Impossible to retry."})},e.end=function(){},d.getLabel=function(){return"command"},d.getPath=function(){return e.path},d.getOption=function(a){return e.option[a]},d.validate=function(a){d.validateState()},d.getTried=function(){return e.tried},d.setMaxRetry=function(a){e.option.max_retry=a},d.execute=function(a){d.validate(a),e.tried++,a.execute(d)},d.executeOn=function(a){},d.validateState=function(){if(e.path==="")throw b({command:d,message:"Path is empty"})},d.done=function(a){e.respond({status:p(),value:a}),e.done(a),e.end()},d.fail=function(a){e.option.max_retry===0||e.tried<e.option.max_retry?e.retry():(e.respond({status:q(),error:a}),e.fail(a),e.end())},d.onResponseDo=function(a){e.respond=a},d.onDoneDo=function(a){e.done=a},d.onFailDo=function(a){e.fail=a},d.onEndDo=function(a){e.end=a},d.onRetryDo=function(a){e.retry=a},d.serialized=function(){return{label:d.getLabel(),tried:e.tried,max_retry:e.max_retry,path:e.path,option:e.option}},d.canBeRestored=function(){return!0},d.clone=function(){return j(d.serialized(),c)},d)},k=function(a,b){var c=j(a,b);a=a||{},b=b||{},c.getLabel=function(){return"getDocumentList"},c.executeOn=function(a){a.getDocumentList(c)},c.canBeRestored=function(){return!1};var d=c.done;return c.done=function(a){var b;if(a)for(b=0;b<a.length;b+=1)typeof a[b].last_modified!="number"&&(a[b].last_modified=(new Date(a[b].last_modified)).getTime()),typeof a[b].creation_date!="number"&&(a[b].creation_date=(new Date(a[b].creation_date)).getTime());d(a)},c},l=function(a,b){var c=j(a,b);a=a||{},b=b||{},c.getLabel=function(){return"loadDocument"},c.executeOn=function(a){a.loadDocument(c)},c.canBeRestored=function(){return!1};var d=c.done;return c.done=function(a){a&&(typeof a.last_modified!="number"&&(a.last_modified=(new Date(a.last_modified)).getTime()),typeof a.creation_date!="number"&&(a.creation_date=(new Date(a.creation_date)).getTime())),d(a)},c},m=function(a,b){var c=j(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"removeDocument"},c.executeOn=function(a){a.removeDocument(c)},c},n=function(a,c){var d=j(a,c);a=a||{},c=c||{};var e={};e.content=a.content,d.getLabel=function(){return"saveDocument"},d.getContent=function(){return e.content};var f=d.validate;d.validate=function(a){if(typeof e.content!="string")throw b({command:d,message:"No data to save"});f(a)},d.executeOn=function(a){a.saveDocument(d)};var g=d.serialized;return d.serialized=function(){var a=g();return a.content=e.content,a},d},o=function(a,b){var c={};return a=a||{},b=b||{},c.getLabel=function(){return"job status"},c.canStart=function(){},c.canRestart=function(){},c.serialized=function(){return{label:c.getLabel()}},c.isWaitStatus=function(){return!1},c},p=function(a,b){var c=o(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"done"},c.canStart=function(){return!1},c.canRestart=function(){return!1},c},q=function(a,b){var c=o(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"fail"},c.canStart=function(){return!1},c.canRestart=function(){return!0},c},r=function(a,b){var c=o(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"initial"},c.canStart=function(){return!0},c.canRestart=function(){return!0},c},s=function(a,b){var c=o(a,b);return a=a||{},b=b||{},c.getLabel=function(){return"on going"},c.canStart=function(){return!1},c.canRestart=function(){return!1},c},t=function(a,b){var c=o(a,b);a=a||{},b=b||{};var d={};return d.job_id_a=a.job_id_array||[],d.threshold=0,c.getLabel=function(){return"wait"},d.refreshJobIdArray=function(){var a=[],c;for(c=0;c<d.job_id_a.length;c+=1)b.jobManager.jobIdExists(d.job_id_a[c])&&a.push(d.job_id_a[c]);d.job_id_a=a},c.waitForJob=function(a){var b;for(b=0;b<d.job_id_a.length;b+=1)if(d.job_id_a[b]===a.getId())return;d.job_id_a.push(a.getId())},c.dontWaitForJob=function(a){var b,c=[];for(b=0;b<d.job_id_a.length;b+=1)d.job_id_a[b]!==a.getId()&&c.push(d.job_id_a[b]);d.job_id_a=c},c.waitForTime=function(a){d.threshold=Date.now()+a},c.stopWaitForTime=function(){d.threshold=0},c.canStart=function(){return d.refreshJobIdArray(),d.job_id_a.length===0&&Date.now()>=d.threshold},c.canRestart=function(){return c.canStart()},c.serialized=function(){return{label:c.getLabel(),waitfortime:d.threshold,waitforjob:d.job_id_a}},c.isWaitStatus=function(){return!0},c},u=function(a,b){var c={};a=a||{},b=b||{};var d={};return d.id=b.jobIdHandler.nextId(),d.command=a.command,d.storage=a.storage,d.status=r(),d.date=new Date,function(){if(!d.storage)throw g({job:c,message:"No storage set"});if(!d.command)throw g({job:c,message:"No command set"})}(),c.getCommand=function(){return d.command},c.getStatus=function(){return d.status},c.getId=function(){return d.id},c.getStorage=function(){return d.storage},c.getDate=function(){return d.date},c.isReady=function(){return d.tried===0?d.status.canStart():d.status.canRestart()},c.serialized=function(){return{id:d.id,date:d.date.getTime(),status:d.status.serialized(),command:d.command.serialized(),storage:d.storage.serialized()}},c.waitForJob=function(a){d.status.getLabel()!=="wait"&&(d.status=t({},b)),d.status.waitForJob(a)},c.dontWaitFor=function(a){d.status.getLabel()==="wait"&&d.status.dontWaitForJob(a)},c.waitForTime=function(a){d.status.getLabel()!=="wait"&&(d.status=t({},b)),d.status.waitForTime(a)},c.stopWaitForTime=function(){d.status.getLabel()==="wait"&&d.status.stopWaitForTime()},c.update=function(a){d.command.setMaxRetry(-1),d.command.fail({status:0,statusText:"Replaced",message:"Job has been replaced by another one."}),d.date=a.getDate(),d.command=a.getCommand(),d.status=a.getStatus()},c.execute=function(){if(d.max_retry!==0&&d.tried>=d.max_retry)throw f({job:c,message:"The job was invoked too much time."});if(!c.isReady())throw e({message:"Can not execute this job."});d.status=s(),d.command.onRetryDo(function(){var a=d.command.getTried();a=a*a*200,a>1e4&&(a=1e4),c.waitForTime(a)}),d.command.onEndDo(function(){b.jobManager.terminateJob(c)}),d.command.execute(d.storage)},c},v=function(a,b){var c={};a=a||{},b=b||{};var d=[],e=a.name||"",f=a.announcer||{};return c.add=function(a){d.push(a)},c.remove=function(a){var b,c=[];for(b=0;b<d.length;b+=1)d[b]!==a&&c.push(d[b]);d=c},c.register=function(){f.register(c)},c.unregister=function(){f.unregister(c)},c.trigger=function(a){var b;for(b=0;b<d.length;b++)d[b].apply(null,a)},c},w=function(a,b){var c=function(a,b){var c={};a=a||{},b=b||{};var d={};return d.id=a.id||0,d.interval=400,d.interval_id=null,d.touch=function(){LocalOrCookieStorage.setItem("jio/id/"+d.id,Date.now())},c.setId=function(a){d.id=a},c.setIntervalDelay=function(a){d.interval=a},c.getIntervalDelay=function(){return d.interval},c.start=function(){d.interval_id||(d.touch(),d.interval_id=setInterval(function(){d.touch()},d.interval))},c.stop=function(){d.interval_id!==null&&(clearInterval(d.interval_id),d.interval_id=null)},c}(),d=function(a,b){var c={};a=a||{},b=b||{};var d={};return c.register=function(a){d[a]||(d[a]=v())},c.unregister=function(a){d[a]&&delete d[a]},c.at=function(a){return d[a]},c.on=function(a,b){c.register(a),c.at(a).add(b)},c.trigger=function(a,b){c.at(a).trigger(b)},c}(),e=function(a,b){var c={};a=a||{},b=b||{};var d=0;return c.nextId=function(){return d=d+1,d},c}(),f=function(a,b){var c={};a=a||{},b=b||{};var d="jio/job_array",e={};return e.id=a.id,e.interval_id=null,e.interval=200,e.job_a=[],b.jobManager=c,b.jobIdHandler=c,e.getJobArrayName=function(){return d+"/"+e.id},e.getJobArray=function(){return LocalOrCookieStorage.getItem(e.getJobArrayName())||[]},e.copyJobArrayToLocal=function(){var a=[],b;for(b=0;b<e.job_a.length;b+=1)a.push(e.job_a[b].serialized());LocalOrCookieStorage.setItem(e.getJobArrayName(),a)},e.removeJob=function(a){var b,c=[];for(b=0;b<e.job_a.length;b+=1)e.job_a[b]!==a&&c.push(e.job_a[b]);e.job_a=c,e.copyJobArrayToLocal()},c.setId=function(a){e.id=a},c.start=function(){var a;e.interval_id===null&&(e.interval_id=setInterval(function(){e.restoreOldJio();for(a=0;a<e.job_a.length;a+=1)c.execute(e.job_a[a])},e.interval))},c.stop=function(){e.interval_id!==null&&(clearInterval(e.interval_id),e.interval_id=null,e.job_a.length===0&&LocalOrCookieStorage.deleteItem(e.getJobArrayName()))},e.restoreOldJio=function(){var a,b;e.lastrestore=e.lastrestore||0;if(e.lastrestore>Date.now()-2e3)return;b=LocalOrCookieStorage.getItem("jio/id_array")||[];for(a=0;a<b.length;a+=1)e.restoreOldJioId(b[a]);e.lastrestore=Date.now()},e.restoreOldJioId=function(a){var b;b=LocalOrCookieStorage.getItem("jio/id/"+a)||0,b<Date.now()-1e4&&(e.restoreOldJobFromJioId(a),e.removeOldJioId(a),e.removeJobArrayFromJioId(a))},e.restoreOldJobFromJioId=function(a){var d,e;e=LocalOrCookieStorage.getItem("jio/job_array/"+a)||[];for(d=0;d<e.length;d+=1){var f=j(e[d].command,b);f.canBeRestored()&&c.addJob(u({storage:x.storage(e[d].storage,b),command:f},b))}},e.removeOldJioId=function(a){var b,c,d=[];c=LocalOrCookieStorage.getItem("jio/id_array")||[];for(b=0;b<c.length;b+=1)c[b]!==a&&d.push(c[b]);LocalOrCookieStorage.setItem("jio/id_array",d),LocalOrCookieStorage.deleteItem("jio/id/"+a)},e.removeJobArrayFromJioId=function(a){LocalOrCookieStorage.deleteItem("jio/job_array/"+a)},c.execute=function(a){try{a.execute()}catch(b){switch(b.name){case"jobNotReadyException":break;case"tooMuchTriesJobException":break;default:throw b}}e.copyJobArrayToLocal()},c.jobIdExists=function(a){var b;for(b=0;b<e.job_a.length;b+=1)if(e.job_a[b].getId()===a)return!0;return!1},c.terminateJob=function(a){e.removeJob(a)},c.addJob=function(a){var b=c.validateJobAccordingToJobList(e.job_a,a);e.appendJob(a,b)},c.validateJobAccordingToJobList=function(a,b){var c,d=[];for(c=0;c<a.length;c+=1)d.push(g.validateJobAccordingToJob(a[c],b));return d},e.appendJob=function(a,b){var c;if(e.job_a.length!==b.length)throw new RangeError("Array out of bound");for(c=0;c<b.length;c+=1)if(b[c].action==="dont accept")return;for(c=0;c<b.length;c+=1)switch(b[c].action){case"eliminate":e.removeJob(b[c].job);break;case"update":b[c].job.update(a),e.copyJobArrayToLocal();return;case"wait":a.waitForJob(b[c].job);break;default:}e.job_a.push(a),e.copyJobArrayToLocal()},c}(),g=function(a,b){var c={},d={};return d.compare={},d.action={},c.eliminate=function(){return"eliminate"},c.update=function(){return"update"},c.dontAccept=function(){return"dont accept"},c.wait=function(){return"wait"},c.none=function(){return"none"},c.default_action=c.none,c.default_compare=function(a,b){return a.getCommand().getPath()===b.getCommand().getPath()&&JSON.stringify(a.getStorage().serialized())===JSON.stringify(b.getStorage().serialized())},d.getAction=function(a,b){var e,f,g;return e=a.getCommand().getLabel(),f=b.getCommand().getLabel(),g=a.getStatus().getLabel()==="on going"?"on going":"not on going",d.action[e]&&d.action[e][g]&&d.action[e][g][f]?d.action[e][g][f](a,b):c.default_action(a,b)},d.canCompare=function(a,b){var e=a.getCommand().getLabel(),f=b.getCommand().getLabel();return d.compare[e]&&d.compare[f]?d.compare[e][f](a,b):c.default_compare(a,b)},c.validateJobAccordingToJob=function(a,b){return d.canCompare(a,b)?{action:d.getAction(a,b),job:a}:{action:c.default_action(a,b),job:a}},c.addActionRule=function(a,b,c,e){var f=b?"on going":"not on going";d.action[a]=d.action[a]||{},d.action[a][f]=d.action[a][f]||{},d.action[a][f][c]=e},c.addCompareRule=function(a,b,c){d.compare[a]=d.compare[a]||{},d.compare[a][b]=c},c.addActionRule("saveDocument",!0,"saveDocument",function(a,b){return a.getCommand().getContent()===b.getCommand().getContent()?c.dontAccept():c.wait()}),c.addActionRule("saveDocument",!0,"loadDocument",c.wait),c.addActionRule("saveDocument",!0,"removeDocument",c.wait),c.addActionRule("saveDocument",!1,"saveDocument",c.update),c.addActionRule("saveDocument",!1,"loadDocument",c.wait),c.addActionRule("saveDocument",!1,"removeDocument",c.eliminate),c.addActionRule("loadDocument",!0,"saveDocument",c.wait),c.addActionRule("loadDocument",!0,"loadDocument",c.dontAccept),c.addActionRule("loadDocument",!0,"removeDocument",c.wait),c.addActionRule("loadDocument",!1,"saveDocument",c.wait),c.addActionRule("loadDocument",!1,"loadDocument",c.update),c.addActionRule("loadDocument",!1,"removeDocument",c.wait),c.addActionRule("removeDocument",!0,"loadDocument",c.dontAccept),c.addActionRule("removeDocument",!0,"removeDocument",c.dontAccept),c.addActionRule("removeDocument",!1,"saveDocument",c.eliminate),c.addActionRule("removeDocument",!1,"loadDocument",c.dontAccept),c.addActionRule("removeDocument",!1,"removeDocument",c.update),c.addActionRule("getDocumentList",!0,"getDocumentList",c.dontAccept),c.addActionRule("getDocumentList",!1,"getDocumentList",c.update),c}(),h={};a=a||{},b=b||{};var i={},o="jio/id_array";return i.id=null,b.jobManager=f,b.jobIdHandler=e,i.storage=x.storage(a,b),i.init=function(){if(i.id===null){var a,b=LocalOrCookieStorage.getItem(o)||[];i.id=1;for(a=0;a<b.length;a+=1)b[a]>=i.id&&(i.id=b[a]+1);b.push(i.id),LocalOrCookieStorage.setItem(o,b),c.setId(i.id),f.setId(i.id)}},h.start=function(){i.init(),c.start(),f.start()},h.stop=function(){f.stop()},h.close=function(){c.stop(),f.stop(),i.id=null},h.start(),h.getId=function(){return i.id},h.getJobRules=function(){return g},h.validateStorageDescription=function(a){return x.storage(a,b).isValid()},h.saveDocument=function(a,c,d,e){d=d||{},d.onResponse=d.onResponse||function(){},d.onDone=d.onDone||function(){},d.onFail=d.onFail||function(){},d.max_retry=d.max_retry||0,f.addJob(u({storage:e?x.storage(e,b):i.storage,command:n({path:a,content:c,option:d})},b))},h.loadDocument=function(a,c,d){c=c||{},c.onResponse=c.onResponse||function(){},c.onDone=c.onDone||function(){},c.onFail=c.onFail||function(){},c.max_retry=c.max_retry||0,c.metadata_only=c.metadata_only!==undefined?c.metadata_only:!1,f.addJob(u({storage:d?x.storage(d,b):i.storage,command:l({path:a,option:c})},b))},h.removeDocument=function(a,c,d){c=c||{},c.onResponse=c.onResponse||function(){},c.onDone=c.onDone||function(){},c.onFail=c.onFail||function(){},c.max_retry=c.max_retry||0,f.addJob(u({storage:d?x.storage(d,b):i.storage,command:m({path:a,option:c})},b))},h.getDocumentList=function(a,c,d){c=c||{},c.onResponse=c.onResponse||function(){},c.onDone=c.onDone||function(){},c.onFail=c.onFail||function(){},c.max_retry=c.max_retry||0,c.metadata_only=c.metadata_only!==undefined?c.metadata_only:!0,f.addJob(u({storage:d?x.storage(d,b):i.storage,command:k({path:a,option:c})},b))},h},x=function(a,b){var c={};a=a||{},b=b||{};var e={base:h,handler:i};return c.storage=function(a,b,c){a=a||{};var f=c||a.type||"base";if(!e[f])throw d({type:f,message:"Storage does not exists."});return e[f](a,b)},c.newJio=function(a){var b=a;return typeof b=="string"&&(b=JSON.parse(b)),b=b||{type:"base"},w(a)},c.addStorageType=function(a,b){b=b||function(){return null};if(e[a])throw d({type:a,message:"Already known."});e[a]=b},c}();return x}();
\ No newline at end of file
/*! JIO Storage - v0.1.0 - 2012-06-05
/*! JIO Storage - v0.1.0 - 2012-06-14
* Copyright (c) 2012 Nexedi; Licensed */
(function () {
var jioStorageLoader =
function ( LocalOrCookieStorage, $, Base64, sjcl, Jio) {
(function(LocalOrCookieStorage, $, Base64, sjcl, Jio) {
////////////////////////////////////////////////////////////////////////////
// Tools
// end Tools
////////////////////////////////////////////////////////////////////////////
var newLocalStorage = function ( spec, my ) {
var that = Jio.storage( spec, my, 'base' ), priv = {};
////////////////////////////////////////////////////////////////////////////
// Classes
var newLocalStorage,newDAVStorage,newReplicateStorage,
newIndexedStorage,newCryptedStorage;
// end Classes
////////////////////////////////////////////////////////////////////////////
priv.username = spec.username || '';
priv.applicationname = spec.applicationname || 'untitled';
////////////////////////////////////////////////////////////////////////////
// Local Storage
/**
* JIO Local Storage. Type = 'local'.
* It is a database located in the browser local storage.
*/
newLocalStorage = function ( spec, my ) {
// LocalStorage constructor
var storage_user_array_name = 'jio/local_user_array';
var storage_file_array_name = 'jio/local_file_name_array/' +
priv.username + '/' + priv.applicationname;
var that = Jio.newBaseStorage( spec, my ), priv = {};
var super_serialized = that.serialized;
that.serialized = function() {
var o = super_serialized();
o.applicationname = priv.applicationname;
o.username = priv.username;
return o;
};
priv.storage_user_array_name = 'jio/local_user_array';
priv.storage_file_array_name = 'jio/local_file_name_array/' +
that.getStorageUserName() + '/' + that.getApplicantID();
that.validateState = function() {
if (priv.username) {
return '';
}
return 'Need at least one parameter: "username".';
};
/**
* Returns a list of users.
* @method getUserArray
* @return {array} The list of users.
*/
priv.getUserArray = function () {
return LocalOrCookieStorage.getItem(
priv.storage_user_array_name) || [];
};
/**
* Returns a list of users.
* @method getUserArray
* @return {array} The list of users.
*/
priv.getUserArray = function () {
return LocalOrCookieStorage.getItem(
storage_user_array_name) || [];
};
/**
* Adds a user to the user list.
* @method addUser
* @param {string} user_name The user name.
*/
priv.addUser = function (user_name) {
var user_array = priv.getUserArray();
user_array.push(user_name);
LocalOrCookieStorage.setItem(priv.storage_user_array_name,
user_array);
};
/**
* Adds a user to the user list.
* @method addUser
* @param {string} user_name The user name.
*/
priv.addUser = function (user_name) {
var user_array = priv.getUserArray();
user_array.push(user_name);
LocalOrCookieStorage.setItem(storage_user_array_name,
user_array);
};
/**
* checks if a user exists in the user array.
* @method userExists
* @param {string} user_name The user name
* @return {boolean} true if exist, else false
*/
priv.userExists = function (user_name) {
var user_array = priv.getUserArray(), i, l;
for (i = 0, l = user_array.length; i < l; i += 1) {
if (user_array[i] === user_name) {
return true;
}
/**
* checks if a user exists in the user array.
* @method userExists
* @param {string} user_name The user name
* @return {boolean} true if exist, else false
*/
priv.userExists = function (user_name) {
var user_array = priv.getUserArray(), i, l;
for (i = 0, l = user_array.length; i < l; i += 1) {
if (user_array[i] === user_name) {
return true;
}
return false;
};
}
return false;
};
/**
* Returns the file names of all existing files owned by the user.
* @method getFileNameArray
* @return {array} All the existing file paths.
*/
priv.getFileNameArray = function () {
return LocalOrCookieStorage.getItem(
priv.storage_file_array_name) || [];
};
/**
* Returns the file names of all existing files owned by the user.
* @method getFileNameArray
* @return {array} All the existing file paths.
*/
priv.getFileNameArray = function () {
return LocalOrCookieStorage.getItem(
storage_file_array_name) || [];
};
/**
* Adds a file name to the local file name array.
* @method addFileName
* @param {string} file_name The new file name.
*/
priv.addFileName = function (file_name) {
var file_name_array = priv.getFileNameArray();
file_name_array.push(file_name);
LocalOrCookieStorage.setItem(priv.storage_file_array_name,
file_name_array);
};
/**
* Adds a file name to the local file name array.
* @method addFileName
* @param {string} file_name The new file name.
*/
priv.addFileName = function (file_name) {
var file_name_array = priv.getFileNameArray();
file_name_array.push(file_name);
LocalOrCookieStorage.setItem(storage_file_array_name,
file_name_array);
};
/**
* Removes a file name from the local file name array.
* @method removeFileName
* @param {string} file_name The file name to remove.
*/
priv.removeFileName = function (file_name) {
var i, l, array = priv.getFileNameArray(), new_array = [];
for (i = 0, l = array.length; i < l; i+= 1) {
if (array[i] !== file_name) {
new_array.push(array[i]);
}
/**
* Removes a file name from the local file name array.
* @method removeFileName
* @param {string} file_name The file name to remove.
*/
priv.removeFileName = function (file_name) {
var i, l, array = priv.getFileNameArray(), new_array = [];
for (i = 0, l = array.length; i < l; i+= 1) {
if (array[i] !== file_name) {
new_array.push(array[i]);
}
LocalOrCookieStorage.setItem(priv.storage_file_array_name,
new_array);
};
/**
* Checks the availability of a user name set in the job.
* It will check if the user is set in the local user object
* @method checkNameAvailability
*/
that.checkNameAvailability = function () {
setTimeout(function () {
that.done(!priv.userExists(that.getUserName()));
}, 100);
}; // end checkNameAvailability
/**
* Saves a document in the local storage.
* It will store the file in 'jio/local/USR/APP/FILE_NAME'.
* @method saveDocument
*/
that.saveDocument = function () {
// wait a little in order to simulate asynchronous saving
setTimeout (function () {
var doc = null, path =
'jio/local/'+that.getStorageUserName()+'/'+
that.getApplicantID()+'/'+
that.getFileName();
// reading
doc = LocalOrCookieStorage.getItem(path);
if (!doc) {
// create document
doc = {
'name': that.getFileName(),
'content': that.getFileContent(),
'creation_date': Date.now(),
'last_modified': Date.now()
};
if (!priv.userExists(that.getStorageUserName())) {
priv.addUser (that.getStorageUserName());
}
priv.addFileName(that.getFileName());
} else {
// overwriting
doc.last_modified = Date.now();
doc.content = that.getFileContent();
}
LocalOrCookieStorage.setItem(path, doc);
return that.done();
}, 100);
}; // end saveDocument
/**
* Loads a document from the local storage.
* It will load file in 'jio/local/USR/APP/FILE_NAME'.
* You can add an 'options' object to the job, it can contain:
* - metadata_only {boolean} default false, retrieve the file metadata
* only if true.
* - content_only {boolean} default false, retrieve the file content
* only if true.
* @method loadDocument
*/
that.loadDocument = function () {
// document object is {'name':string,'content':string,
// 'creation_date':date,'last_modified':date}
setTimeout(function () {
var doc = null, settings = that.cloneOptionObject();
doc = LocalOrCookieStorage.getItem(
'jio/local/'+that.getStorageUserName()+'/'+
that.getApplicantID()+'/'+that.getFileName());
if (!doc) {
that.fail({status:404,statusText:'Not Found.',
message:'Document "'+ that.getFileName() +
'" not found in localStorage.'});
} else {
if (settings.metadata_only) {
delete doc.content;
} else if (settings.content_only) {
delete doc.last_modified;
delete doc.creation_date;
}
that.done(doc);
}
}, 100);
}; // end loadDocument
/**
* Gets a document list from the local storage.
* It will retreive an array containing files meta data owned by
* the user.
* @method getDocumentList
*/
that.getDocumentList = function () {
// the list is [object,object] -> object = {'name':string,
// 'last_modified':date,'creation_date':date}
setTimeout(function () {
var new_array = [], array = [], i, l, k = 'key',
path = 'jio/local/'+that.getStorageUserName()+'/'+
that.getApplicantID(), file_object = {};
array = priv.getFileNameArray();
for (i = 0, l = array.length; i < l; i += 1) {
file_object =
LocalOrCookieStorage.getItem(path+'/'+array[i]);
if (file_object) {
new_array.push ({
'name':file_object.name,
'creation_date':file_object.creation_date,
'last_modified':file_object.last_modified});
}
}
that.done(new_array);
}, 100);
}; // end getDocumentList
/**
* Removes a document from the local storage.
* It will also remove the path from the local file array.
* @method removeDocument
*/
that.removeDocument = function () {
setTimeout (function () {
var path = 'jio/local/'+
that.getStorageUserName()+'/'+
that.getApplicantID()+'/'+
that.getFileName();
// deleting
LocalOrCookieStorage.deleteItem(path);
priv.removeFileName(that.getFileName());
return that.done();
}, 100);
};
return that;
}
LocalOrCookieStorage.setItem(storage_file_array_name,
new_array);
};
// end Local Storage
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// DAVStorage
newDAVStorage = function ( spec, my ) {
var that = Jio.newBaseStorage( spec, my );
that.mkcol = function ( options ) {
// create folders in dav storage, synchronously
// options : contains mkcol list
// options.url : the davstorage url
// options.path: if path=/foo/bar then creates url/dav/foo/bar
// options.success: the function called if success
// options.user_name: the user name
// options.password: the password
// TODO this method is not working !!!
var settings = $.extend ({
'success':function(){},'error':function(){}},options),
split_path = ['split_path'], tmp_path = 'temp/path';
/**
* Saves a document in the local storage.
* It will store the file in 'jio/local/USR/APP/FILE_NAME'.
* @method saveDocument
*/
that.saveDocument = function (command) {
// wait a little in order to simulate asynchronous saving
setTimeout (function () {
var doc = null, path =
'jio/local/'+priv.username+'/'+
priv.applicationname+'/'+
command.getPath();
// reading
doc = LocalOrCookieStorage.getItem(path);
if (!doc) {
// create document
doc = {
'name': command.getPath(),
'content': command.getContent(),
'creation_date': Date.now(),
'last_modified': Date.now()
};
if (!priv.userExists(priv.username)) {
priv.addUser (priv.username);
}
priv.addFileName(command.getPath());
} else {
// overwriting
doc.last_modified = Date.now();
doc.content = command.getContent();
}
LocalOrCookieStorage.setItem(path, doc);
that.done();
}, 100);
}; // end saveDocument
// if pathstep is not defined, then split the settings.path
// and do mkcol recursively
if (!settings.pathsteps) {
settings.pathsteps = 1;
that.mkcol(settings);
/**
* Loads a document from the local storage.
* It will load file in 'jio/local/USR/APP/FILE_NAME'.
* You can add an 'options' object to the job, it can contain:
* - metadata_only {boolean} default false, retrieve the file metadata
* only if true.
* @method loadDocument
*/
that.loadDocument = function (command) {
// document object is {'name':string,'content':string,
// 'creation_date':date,'last_modified':date}
setTimeout(function () {
var doc = null;
doc = LocalOrCookieStorage.getItem(
'jio/local/'+priv.username+'/'+
priv.applicationname+'/'+command.getPath());
if (!doc) {
that.fail(command,{status:404,statusText:'Not Found.',
message:'Document "'+ command.getPath() +
'" not found in localStorage.'});
} else {
split_path = settings.path.split('/');
// // check if the path is terminated by '/'
// if (split_path[split_path.length-1] == '') {
// split_path.length --;
// }
// check if the pathstep is lower than the longer
if (settings.pathsteps >= split_path.length-1) {
return settings.success();
if (command.getOption('metadata_only')) {
delete doc.content;
}
split_path.length = settings.pathsteps + 1;
settings.pathsteps++;
tmp_path = split_path.join('/');
// alert(settings.url + tmp_path);
$.ajax ( {
url: settings.url + tmp_path,
type: 'MKCOL',
async: true,
headers: {'Authorization': 'Basic '+Base64.encode(
settings.user_name + ':' +
settings.password ), Depth: '1'},
// xhrFields: {withCredentials: 'true'}, // cross domain
success: function () {
// done
that.mkcol(settings);
},
error: function (type) {
// alert(JSON.stringify(type));
// switch (type.status) {
// case 405: // Method Not Allowed
// // already exists
// t.mkcol(settings);
// break;
// default:
settings.error();
// break;
// }
}
} );
that.done(doc);
}
};
}, 100);
}; // end loadDocument
that.checkNameAvailability = function () {
// checks the availability of the [job.user_name].
// if the name already exists, it is not available.
// this.job.storage: the storage informations.
// this.job.storage.url: the dav storage url.
// this.job.user_name: the name we want to check.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
$.ajax ( {
url: that.getStorageURL() + '/dav/' +
that.getStorageUserName() + '/',
async: true,
type: 'PROPFIND',
dataType: 'xml',
headers: {'Authorization': 'Basic '+Base64.encode(
that.getStorageUserName() + ':' +
that.getStoragePassword() ), Depth: '1'},
success: function (xmlData) {
that.done(false);
},
error: function (type) {
if (type.status === 404) {
that.done(true);
/**
* Gets a document list from the local storage.
* It will retreive an array containing files meta data owned by
* the user.
* @method getDocumentList
*/
that.getDocumentList = function (command) {
// the list is [object,object] -> object = {'name':string,
// 'last_modified':date,'creation_date':date}
setTimeout(function () {
var new_array = [], array = [], i, l, k = 'key',
path = 'jio/local/'+priv.username+'/'+ priv.applicationname,
file_object = {};
array = priv.getFileNameArray();
for (i = 0, l = array.length; i < l; i += 1) {
file_object =
LocalOrCookieStorage.getItem(path+'/'+array[i]);
if (file_object) {
if (command.getOption('metadata_only')) {
new_array.push ({
name:file_object.name,
creation_date:file_object.creation_date,
last_modified:file_object.last_modified});
} else {
type.message = 'Cannot check availability of "' +
that.getUserName() + '" into DAVStorage.';
that.fail(type);
new_array.push ({
name:file_object.name,
content:file_object.content,
creation_date:file_object.creation_date,
last_modified:file_object.last_modified});
}
}
} );
};
that.saveDocument = function () {
// Save a document in a DAVStorage
// this.job.storage: the storage informations.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
// this.job.applicant.ID: the applicant ID.
// this.job.name: the document name.
// this.job.content: the document content.
// TODO if path of /dav/user/applic does not exists, it won't work!
//// save on dav
$.ajax ( {
url: that.getStorageURL() + '/dav/' +
that.getStorageUserName() + '/' +
that.getApplicantID() + '/' +
that.getFileName(),
type: 'PUT',
data: that.getFileContent(),
async: true,
dataType: 'text', // TODO is it necessary ?
headers: {'Authorization':'Basic '+Base64.encode(
that.getStorageUserName()+':'+that.getStoragePassword())},
// xhrFields: {withCredentials: 'true'}, // cross domain
success: function () {
that.done();
},
error: function (type) {
type.message = 'Cannot save "' + that.getFileName() +
'" into DAVStorage.';
that.fail(type);
}
} );
//// end saving on dav
};
that.loadDocument = function () {
// Load a document from a DAVStorage. It returns a document object
// containing all information of the document and its content.
// this.job.name: the document name we want to load.
// this.job.storage: the storage informations.
// this.job.storage.url: the dav storage url.
// this.job.storage.userName: the user name.
// this.job.storage.password: the user password.
// this.job.options.getContent: if true, also get the file content.
// document object is {'name':string,'content':string,
// 'creation_date':date,'last_modified':date}
var doc = {},
settings = that.cloneOptionObject(),
getContent = function () {
$.ajax ( {
url: that.getStorageURL() + '/dav/' +
that.getStorageUserName() + '/' +
that.getApplicantID() + '/' +
that.getFileName(),
type: "GET",
async: true,
dataType: 'text', // TODO is it necessary ?
headers: {'Authorization':'Basic '+Base64.encode(
that.getStorageUserName() + ':' +
that.getStoragePassword() )},
// xhrFields: {withCredentials: 'true'}, // cross domain
success: function (content) {
doc.content = content;
that.done(doc);
},
error: function (type) {
if (type.status === 404) {
type.message = 'Document "' +
that.getFileName() +
'" not found in localStorage.';
} else {
type.message =
'Cannot load "' + that.getFileName() +
'" from DAVStorage.';
}
that.fail(type);
}
} );
};
doc.name = that.getFileName();
if (settings.content_only) {
getContent();
return;
}
// Get properties
$.ajax ( {
url: that.getStorageURL() + '/dav/' +
that.getStorageUserName() + '/' +
that.getApplicantID() + '/' +
that.getFileName(),
type: "PROPFIND",
async: true,
dataType: 'xml',
headers: {'Authorization':'Basic '+Base64.encode(
that.getStorageUserName() + ':' +
that.getStoragePassword() )},
success: function (xmlData) {
// doc.last_modified =
$(xmlData).find(
'lp1\\:getlastmodified, getlastmodified'
).each( function () {
doc.last_modified = $(this).text();
});
$(xmlData).find(
'lp1\\:creationdate, creationdate'
).each( function () {
doc.creation_date = $(this).text();
});
if (!settings.metadata_only) {
getContent();
} else {
that.done(doc);
}
},
error: function (type) {
type.message = 'Cannot load "' + that.getFileName() +
'" informations from DAVStorage.';
that.fail(type);
}
} );
};
that.done(new_array);
}, 100);
}; // end getDocumentList
that.getDocumentList = function () {
// Get a document list from a DAVStorage. It returns a document
// array containing all the user documents informations.
// this.job.storage: the storage informations.
// this.job.storage.url: the dav storage url.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
// this.job.applicant.ID: the applicant id.
// the list is [object,object] -> object = {'name':string,
// 'last_modified':date,'creation_date':date}
var document_array = [], file = {}, path_array = [];
/**
* Removes a document from the local storage.
* It will also remove the path from the local file array.
* @method removeDocument
*/
that.removeDocument = function (command) {
setTimeout (function () {
var path = 'jio/local/'+
priv.username+'/'+
priv.applicationname+'/'+
command.getPath();
// deleting
LocalOrCookieStorage.deleteItem(path);
priv.removeFileName(command.getPath());
that.done();
}, 100);
};
return that;
};
Jio.addStorageType('local', newLocalStorage);
var newDAVStorage = function ( spec, my ) {
var that = Jio.storage( spec, my, 'base' ), priv = {};
priv.username = spec.username || '';
priv.applicationname = spec.applicationname || 'untitled';
priv.url = spec.url || '';
priv.password = spec.password || ''; // TODO : is it secured ?
var super_serialized = that.serialized;
that.serialized = function() {
var o = super_serialized();
o.username = priv.username;
o.applicationname = priv.applicationname;
o.url = priv.url;
o.password = priv.password; // TODO : not realy secured...
return o;
};
$.ajax ( {
url: that.getStorageURL() + '/dav/' +
that.getStorageUserName() + '/' +
that.getApplicantID() + '/',
async: true,
type: 'PROPFIND',
dataType: 'xml',
headers: {'Authorization': 'Basic '+Base64.encode(
that.getStorageUserName() + ':' +
that.getStoragePassword() ), Depth: '1'},
success: function (xmlData) {
$(xmlData).find(
'D\\:response, response'
).each( function(i,data){
if(i>0) { // exclude parent folder
file = {};
$(data).find('D\\:href, href').each(function(){
path_array = $(this).text().split('/');
file.name =
(path_array[path_array.length-1] ?
path_array[path_array.length-1] :
path_array[path_array.length-2]+'/');
});
if (file.name === '.htaccess' ||
file.name === '.htpasswd') { return; }
$(data).find(
'lp1\\:getlastmodified, getlastmodified'
).each(function () {
file.last_modified = $(this).text();
});
$(data).find(
'lp1\\:creationdate, creationdate'
).each(function () {
file.creation_date = $(this).text();
});
document_array.push (file);
}
});
that.done(document_array);
},
error: function (type) {
type.message =
'Cannot get a document list from DAVStorage.';
that.fail(type);
}
} );
};
/**
* If some other parameters is needed, it returns an error message.
* @method validateState
* @return {string} '' -> ok, 'message' -> error
*/
that.validateState = function() {
if (priv.username && priv.url) {
return '';
}
return 'Need at least 2 parameters: "username" and "url".';
};
that.removeDocument = function () {
// Remove a document from a DAVStorage.
// this.job.name: the document name we want to remove.
// this.job.storage: the storage informations.
// this.job.storage.url: the dav storage url.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
// this.job.applicant.ID: the applicant id.
/**
* Saves a document in the distant dav storage.
* @method saveDocument
*/
that.saveDocument = function (command) {
// TODO if path of /dav/user/applic does not exists, it won't work!
//// save on dav
$.ajax ( {
url: priv.url + '/dav/' +
priv.username + '/' +
priv.applicationname + '/' +
command.getPath(),
type: 'PUT',
data: command.getContent(),
async: true,
dataType: 'text', // TODO is it necessary ?
headers: {'Authorization':'Basic '+Base64.encode(
priv.username+':'+priv.password)},
// xhrFields: {withCredentials: 'true'}, // cross domain
success: function () {
that.done();
},
error: function (type) {
type.message = 'Cannot save "' + command.getPath() +
'" into DAVStorage.';
that.fail(type);
}
} );
//// end saving on dav
};
/**
* Loads a document from a distant dav storage.
* @method loadDocument
*/
that.loadDocument = function (command) {
var doc = {},
getContent = function () {
$.ajax ( {
url: that.getStorageURL() + '/dav/' +
that.getStorageUserName() + '/' +
that.getApplicantID() + '/' +
that.getFileName(),
type: "DELETE",
url: priv.url + '/dav/' +
priv.username + '/' +
priv.applicationname + '/' +
command.getPath(),
type: "GET",
async: true,
dataType: 'text', // TODO is it necessary ?
headers: {'Authorization':'Basic '+Base64.encode(
that.getStorageUserName() + ':' +
that.getStoragePassword() )},
priv.username + ':' + priv.password )},
// xhrFields: {withCredentials: 'true'}, // cross domain
success: function () {
that.done();
success: function (content) {
doc.content = content;
that.done(doc);
},
error: function (type) {
if (type.status === 404) {
that.done();
type.message = 'Document "' +
command.getPath() +
'" not found in localStorage.';
} else {
type.message = 'Cannot remove "' + that.getFileName() +
type.message =
'Cannot load "' + command.getPath() +
'" from DAVStorage.';
that.fail(type);
}
that.fail(type);
}
} );
};
return that;
};
// end DAVStorage
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// ReplicateStorage
newReplicateStorage = function ( spec, my ) {
var that = Jio.newBaseStorage( spec, my ), priv = {};
priv.storageArray = that.getStorageArray();
// TODO Add a tests that check if there is no duplicate storages.
priv.length = priv.storageArray.length;
priv.return_value_array = [];
priv.max_tries = that.getMaxTries();
that.setMaxTries (1);
priv.execJobsFromStorageArray = function (callback) {
var newjob = {}, i;
for (i = 0; i < priv.storageArray.length; i += 1) {
newjob = that.cloneJob();
newjob.max_tries = priv.max_tries;
newjob.storage = priv.storageArray[i];
newjob.callback = callback;
that.addJob ( newjob ) ;
}
};
that.checkNameAvailability = function () {
// Checks the availability of the [job.user_name].
// if the name already exists in a storage, it is not available.
// this.job.user_name: the name we want to check.
// this.job.storage.storageArray: An Array of storages.
var i = 'id', done = false, error_array = [],
res = {'status':'done'}, callback = function (result) {
priv.return_value_array.push(result);
if (!done) {
if (result.status === 'fail') {
res.status = 'fail';
error_array.push(result.error);
} else {
if (result.return_value === false) {
that.done (false);
done = true;
return;
}
}
if (priv.return_value_array.length ===
priv.length) {
if (res.status === 'fail') {
that.fail (
{status:207,
statusText:'Multi-Status',
message:'Some check availability of "' +
that.getUserName() + '" requests have failed.',
array:error_array});
} else {
that.done (true);
}
done = true;
return;
}
}
};
priv.execJobsFromStorageArray(callback);
};
that.saveDocument = function () {
// Save a single document in several storages.
// If a storage failed to save the document.
// this.job.storage: the storage informations.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
// this.job.applicant.ID: the applicant ID.
// this.job.name: the document name.
// this.job.content: the document content.
var res = {'status':'done'}, i = 'id',
done = false, error_array = [],
callback = function (result) {
priv.return_value_array.push(result);
if (!done) {
if (result.status !== 'fail') {
that.done ();
done = true;
} else {
error_array.push(result.error);
if (priv.return_value_array.length ===
priv.length) {
that.fail (
{status:207,
statusText:'Multi-Status',
message:'All save "' + that.getFileName() +
'" requests have failed.',
array:error_array});
}
}
}
};
priv.execJobsFromStorageArray(callback);
};
that.loadDocument = function () {
// Load a document from several storages. It returns a document
// object containing all information of the document and its
// content. TODO will popup a window which will help us to choose
// the good file if the files are different.
// this.job.name: the document name we want to load.
// this.job.storage: the storage informations.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
// this.job.options.getContent: if true, also get the file content.
var doc = {}, i = 'id',
done = false, error_array = [],
res = {'status':'done'}, callback = function (result) {
priv.return_value_array.push(result);
if (!done) {
if (result.status !== 'fail') {
that.done (result.return_value);
done = true;
} else {
error_array.push(result.error);
if (priv.return_value_array.length ===
priv.length) {
that.fail (
{status:207,
statusText:'Multi-Status',
message:'All load "' + that.getFileName() +
'" requests have failed.',
array:error_array});
}
}
}
};
priv.execJobsFromStorageArray(callback);
};
that.getDocumentList = function () {
// Get a document list from several storages. It returns a document
// array containing all the user documents informations.
// this.job.storage: the storage informations.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
// this.job.applicant.ID: the applicant id.
var res = {'status':'done'}, i = 'id',
done = false, error_array = [],
callback = function (result) {
priv.return_value_array.push(result);
if (!done) {
if (result.status !== 'fail') {
that.done (result.return_value);
done = true;
} else {
error_array.push(result.error);
if (priv.return_value_array.length ===
priv.length) {
that.fail (
{status:207,
statusText:'Multi-Status',
message:'All get document list requests'+
' have failed',
array:error_array});
}
}
doc.name = command.getPath(); // TODO : basename
// NOTE : if (command.getOption('content_only') { return getContent(); }
// Get properties
$.ajax ( {
url: priv.url + '/dav/' +
priv.username + '/' +
priv.applicationname + '/' +
command.getPath(),
type: "PROPFIND",
async: true,
dataType: 'xml',
headers: {'Authorization':'Basic '+Base64.encode(
priv.username + ':' + priv.password )},
success: function (xmlData) {
// doc.last_modified =
$(xmlData).find(
'lp1\\:getlastmodified, getlastmodified'
).each( function () {
doc.last_modified = $(this).text();
});
$(xmlData).find(
'lp1\\:creationdate, creationdate'
).each( function () {
doc.creation_date = $(this).text();
});
if (!command.getOption('metadata_only')) {
getContent();
} else {
that.done(doc);
}
};
priv.execJobsFromStorageArray(callback);
};
that.removeDocument = function () {
// Remove a document from several storages.
// this.job.name: the document name we want to remove.
// this.job.storage: the storage informations.
// this.job.storage.user_name: the user name.
// this.job.storage.password: the user password.
// this.job.applicant.ID: the applicant id.
},
error: function (type) {
type.message = 'Cannot load "' + command.getPath() +
'" informations from DAVStorage.';
that.fail(type);
}
} );
};
var res = {'status':'done'}, i = 'key',
done = false, error_array = [],
callback = function (result) {
priv.return_value_array.push(result);
if (!done) {
if (result.status !== 'fail') {
that.done ();
done = true;
} else {
error_array.push(result.error);
if (priv.return_value_array.length ===
priv.length) {
that.fail (
{status:207,
statusText:'Multi-Status',
message:'All remove "' + that.getFileName() +
'" requests have failed.',
array:error_array});
}
/**
* Gets a document list from a distant dav storage.
* @method getDocumentList
*/
that.getDocumentList = function (command) {
var document_array = [], file = {}, path_array = [];
$.ajax ( {
url: priv.url + '/dav/' +
priv.username + '/' +
priv.applicationname + '/',
async: true,
type: 'PROPFIND',
dataType: 'xml',
headers: {'Authorization': 'Basic '+Base64.encode(
priv.username + ':' + priv.password ), Depth: '1'},
success: function (xmlData) {
$(xmlData).find(
'D\\:response, response'
).each( function(i,data){
if(i>0) { // exclude parent folder
file = {};
$(data).find('D\\:href, href').each(function(){
path_array = $(this).text().split('/');
file.name =
(path_array[path_array.length-1] ?
path_array[path_array.length-1] :
path_array[path_array.length-2]+'/');
});
if (file.name === '.htaccess' ||
file.name === '.htpasswd') { return; }
$(data).find(
'lp1\\:getlastmodified, getlastmodified'
).each(function () {
file.last_modified = $(this).text();
});
$(data).find(
'lp1\\:creationdate, creationdate'
).each(function () {
file.creation_date = $(this).text();
});
document_array.push (file);
}
}
};
priv.execJobsFromStorageArray(callback);
};
return that;
});
that.done(document_array);
},
error: function (type) {
type.message =
'Cannot get a document list from DAVStorage.';
that.fail(type);
}
} );
};
// end ReplicateStorage
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Indexed Storage
/**
* JIO Indexed Storage. Type = 'indexed'.
* It retreives files metadata from another storage and keep them
* in a cache so that we can work faster.
* Removes a document from a distant dav storage.
* @method removeDocument
*/
newIndexedStorage = function ( spec, my ) {
// IndexedStorage constructor
var that = Jio.newBaseStorage( spec, my ), priv = {};
priv.storage_array_name = 'jio/indexed_storage_array';
priv.storage_file_array_name = 'jio/indexed_file_array/'+
JSON.stringify (that.getSecondStorage()) + '/' +
that.getApplicantID();
/**
* Check if the indexed storage array exists.
* @method indexedStorageArrayExists
* @return {boolean} true if exists, else false
*/
priv.indexedStorageArrayExists = function () {
return (LocalOrCookieStorage.getItem(
priv.storage_array_name) ? true : false);
};
/**
* Returns a list of indexed storages.
* @method getIndexedStorageArray
* @return {array} The list of indexed storages.
*/
priv.getIndexedStorageArray = function () {
return LocalOrCookieStorage.getItem(
priv.storage_array_name) || [];
};
/**
* Adds a storage to the indexed storage list.
* @method addIndexedStorage
* @param {object} storage The new indexed storage.
*/
priv.addIndexedStorage = function (storage) {
var indexed_storage_array = priv.getIndexedStorageArray();
indexed_storage_array.push(JSON.stringify (storage));
LocalOrCookieStorage.setItem(priv.storage_array_name,
indexed_storage_array);
};
/**
* Checks if a storage exists in the indexed storage list.
* @method isAnIndexedStorage
* @param {object} storage The storage to find.
* @return {boolean} true if found, else false
*/
priv.isAnIndexedStorage = function (storage) {
var json_storae = JSON.stringify (storage),i,l,
array = priv.getIndexedStorageArray();
for (i = 0, l = array.length; i < l; i+= 1) {
if (JSON.stringify(array[i]) === json_storae) {
return true;
that.removeDocument = function (command) {
$.ajax ( {
url: priv.url + '/dav/' +
priv.username + '/' +
priv.applicationname + '/' +
command.getPath(),
type: "DELETE",
async: true,
headers: {'Authorization':'Basic '+Base64.encode(
priv.username + ':' + priv.password )},
// xhrFields: {withCredentials: 'true'}, // cross domain
success: function () {
that.done();
},
error: function (type) {
if (type.status === 404) {
that.done();
} else {
type.message = 'Cannot remove "' + that.getFileName() +
'" from DAVStorage.';
that.fail(type);
}
}
return false;
};
/**
* Checks if the file array exists.
* @method fileArrayExists
* @return {boolean} true if exists, else false
*/
priv.fileArrayExists = function () {
return (LocalOrCookieStorage.getItem (
priv.storage_file_array_name) ? true : false);
};
} );
};
/**
* Returns the file from the indexed storage but not there content.
* @method getFileArray
* @return {array} All the existing file.
*/
priv.getFileArray = function () {
return LocalOrCookieStorage.getItem(
priv.storage_file_array_name) || [];
};
return that;
};
Jio.addStorageType('dav', newDAVStorage);
/**
* Sets the file array list.
* @method setFileArray
* @param {array} file_array The array containing files.
*/
priv.setFileArray = function (file_array) {
return LocalOrCookieStorage.setItem(
priv.storage_file_array_name,
file_array);
};
var newReplicateStorage = function ( spec, my ) {
var that = Jio.storage( spec, my, 'handler' ), priv = {};
/**
* Checks if the file already exists in the array.
* @method isFileIndexed
* @param {string} file_name The file we want to find.
* @return {boolean} true if found, else false
*/
priv.isFileIndexed = function (file_name) {
var i, l, array = priv.getFileArray();
for (i = 0, l = array.length; i < l; i+= 1) {
if (array[i].name === file_name){
return true;
}
}
return false;
};
priv.return_value_array = [];
priv.storagelist = spec.storagelist || [];
priv.nb_storage = priv.storagelist.length;
/**
* Adds a file to the local file array.
* @method addFile
* @param {object} file The new file.
*/
priv.addFile = function (file) {
var file_array = priv.getFileArray();
file_array.push(file);
LocalOrCookieStorage.setItem(priv.storage_file_array_name,
file_array);
};
priv.isTheLast = function () {
return (priv.return_value_array.length === priv.nb_storage);
};
/**
* Removes a file from the local file array.
* @method removeFile
* @param {string} file_name The file to remove.
*/
priv.removeFile = function (file_name) {
var i, l, array = priv.getFileArray(), new_array = [];
for (i = 0, l = array.length; i < l; i+= 1) {
if (array[i].name !== file_name) {
new_array.push(array[i]);
priv.doJob = function (command,errormessage) {
var done = false, error_array = [], i,
onResponseDo = function (result) {
console.log ('respond');
priv.return_value_array.push(result);
},
onFailDo = function (result) {
if (!done) {
console.log ('fail');
error_array.push(result);
if (priv.isTheLast()) {
that.fail (
{status:207,
statusText:'Multi-Status',
message:errormessage,
array:error_array});
}
}
LocalOrCookieStorage.setItem(priv.storage_file_array_name,
new_array);
};
/**
* Updates the storage.
* It will retreive all files from a storage. It is an asynchronous task
* so the update can be on going even if IndexedStorage has already
* returned the result.
* @method update
*/
priv.update = function (callback) {
// retreive list before, and then retreive all files
var getlist_callback = function (result) {
if (result.status === 'done') {
if (!priv.isAnIndexedStorage(that.getSecondStorage())) {
priv.addIndexedStorage(that.getSecondStorage());
}
priv.setFileArray(result.return_value);
}
},
newjob = {
storage: that.getSecondStorage(),
applicant: {ID:that.getApplicantID()},
method: 'getDocumentList',
max_tries: 3,
callback: getlist_callback
};
that.addJob ( newjob );
};
/**
* Checks the availability of a user name set in the job.
* @method checkNameAvailability
*/
that.checkNameAvailability = function () {
var new_job = that.cloneJob();
priv.update();
new_job.storage = that.getSecondStorage();
new_job.callback = function (result) {
if (result.status === 'done') {
that.done(result.return_value);
} else {
that.fail(result.error);
}
};
that.addJob( new_job );
}; // end checkNameAvailability
/**
* Saves a document.
* @method saveDocument
*/
that.saveDocument = function () {
var new_job = that.cloneJob();
new_job.storage = that.getSecondStorage();
new_job.callback = function (result) {
if (result.status === 'done') {
if (!priv.isFileIndexed(that.getFileName())) {
priv.addFile({name:that.getFileName(),
last_modified:0,
creation_date:0});
}
priv.update();
that.done();
} else {
that.fail(result.error);
}
};
that.addJob ( new_job );
}; // end saveDocument
/**
* Loads a document.
* job.options.metadata_only {boolean}
* job.options.content_only {boolean}
* @method loadDocument
*/
that.loadDocument = function () {
var file_array, i, l, new_job,
loadCallback = function (result) {
if (result.status === 'done') {
// if (file_array[i].last_modified !==
// result.return_value.last_modified ||
// file_array[i].creation_date !==
// result.return_value.creation_date) {
// // the file in the index storage is different than
// // the one in the second storage. priv.update will
// // take care of refresh the indexed storage
// }
that.done(result.return_value);
} else {
that.fail(result.error);
}
},
secondLoadDocument = function () {
new_job = that.cloneJob();
new_job.storage = that.getSecondStorage();
new_job.callback = loadCallback;
that.addJob ( new_job );
},
settings = that.cloneOptionObject();
priv.update();
if (settings.metadata_only) {
setTimeout(function () {
if (priv.fileArrayExists()) {
file_array = priv.getFileArray();
for (i = 0, l = file_array.length; i < l; i+= 1) {
if (file_array[i].name === that.getFileName()) {
return that.done(file_array[i]);
}
}
} else {
secondLoadDocument();
}
},100);
} else {
secondLoadDocument();
},
onDoneDo = function (result) {
if (!done) {
console.log ('done');
done = true;
that.done (result);
}
}; // end loadDocument
/**
* Gets a document list.
* @method getDocumentList
*/
that.getDocumentList = function () {
var id;
priv.update();
id = setInterval(function () {
if (priv.fileArrayExists()) {
that.done(priv.getFileArray());
clearInterval(id);
}
},100);
}; // end getDocumentList
/**
* Removes a document.
* @method removeDocument
*/
that.removeDocument = function () {
var new_job = that.cloneJob();
new_job.storage = that.getSecondStorage();
new_job.callback = function (result) {
if (result.status === 'done') {
priv.removeFile(that.getFileName());
priv.update();
that.done();
} else {
that.fail(result.error);
}
};
that.addJob(new_job);
};
return that;
command.setMaxRetry (1);
for (i = 0; i < priv.nb_storage; i+= 1) {
var newcommand = command.clone();
var newstorage = Jio.storage(priv.storagelist[i], my);
newcommand.onResponseDo (onResponseDo);
newcommand.onFailDo (onFailDo);
newcommand.onDoneDo (onDoneDo);
that.addJob (newstorage, newcommand);
}
};
// end Indexed Storage
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
// Crypted Storage
/**
* JIO Crypted Storage. Type = 'crypted'.
* It will encrypt the file and its metadata stringified by JSON.
* Save a document in several storages.
* @method saveDocument
*/
newCryptedStorage = function ( spec, my ) {
// CryptedStorage constructor
var that = Jio.newBaseStorage( spec, my ), priv = {};
// TODO : IT IS NOT SECURE AT ALL!
// WE MUST REWORK CRYPTED STORAGE!
priv.encrypt_param_object = {
"iv":"kaprWwY/Ucr7pumXoTHbpA",
"v":1,
"iter":1000,
"ks":256,
"ts":128,
"mode":"ccm",
"adata":"",
"cipher":"aes",
"salt":"K4bmZG9d704"
};
priv.decrypt_param_object = {
"iv":"kaprWwY/Ucr7pumXoTHbpA",
"ks":256,
"ts":128,
"salt":"K4bmZG9d704"
};
priv.encrypt = function (data,callback,index) {
// end with a callback in order to improve encrypt to an
// asynchronous encryption.
var tmp = sjcl.encrypt (that.getStorageUserName()+':'+
that.getStoragePassword(), data,
priv.encrypt_param_object);
callback(JSON.parse(tmp).ct,index);
};
priv.decrypt = function (data,callback,index,key) {
var tmp, param = $.extend(true,{},priv.decrypt_param_object);
param.ct = data || '';
param = JSON.stringify (param);
try {
tmp = sjcl.decrypt (that.getStorageUserName()+':'+
that.getStoragePassword(),
param);
} catch (e) {
callback({status:0,statusText:'Decrypt Fail',
message:'Unable to decrypt.'},index,key);
return;
}
callback(tmp,index,key);
};
/**
* Checks the availability of a user name set in the job.
* @method checkNameAvailability
*/
that.checkNameAvailability = function () {
var new_job = that.cloneJob();
new_job.storage = that.getSecondStorage();
new_job.callback = function (result) {
if (result.status === 'done') {
that.done(result.return_value);
} else {
that.fail(result.error);
}
};
that.addJob( new_job );
}; // end checkNameAvailability
/**
* Saves a document.
* @method saveDocument
*/
that.saveDocument = function () {
var new_job, new_file_name, newfilecontent,
_1 = function () {
priv.encrypt(that.getFileName(),function(res) {
new_file_name = res;
_2();
});
},
_2 = function () {
priv.encrypt(that.getFileContent(),function(res) {
newfilecontent = res;
_3();
});
},
_3 = function () {
new_job = that.cloneJob();
new_job.name = new_file_name;
new_job.content = newfilecontent;
new_job.storage = that.getSecondStorage();
new_job.callback = function (result) {
if (result.status === 'done') {
that.done();
} else {
that.fail(result.error);
}
};
that.addJob ( new_job );
};
_1();
}; // end saveDocument
that.saveDocument = function (command) {
priv.doJob (
command.clone(),
'All save "'+ command.getPath() +'" requests have failed.');
};
/**
* Loads a document.
* job.options.metadata_only {boolean}
* job.options.content_only {boolean}
* @method loadDocument
*/
that.loadDocument = function () {
var new_job, new_file_name, option = that.cloneOptionObject(),
_1 = function () {
priv.encrypt(that.getFileName(),function(res) {
new_file_name = res;
_2();
});
},
_2 = function () {
new_job = that.cloneJob();
new_job.name = new_file_name;
new_job.storage = that.getSecondStorage();
new_job.callback = loadCallback;
that.addJob ( new_job );
},
loadCallback = function (result) {
if (result.status === 'done') {
result.return_value.name = that.getFileName();
if (option.metadata_only) {
that.done(result.return_value);
} else {
priv.decrypt (result.return_value.content,function(res){
if (typeof res === 'object') {
that.fail({status:0,statusText:'Decrypt Fail',
message:'Unable to decrypt'});
} else {
result.return_value.content = res;
// content only: the second storage should
// manage content_only option, so it is not
// necessary to manage it.
that.done(result.return_value);
}
});
}
} else {
// NOTE : we can re create an error object instead of
// keep the old ex:status=404,message="document 1y59gyl8g
// not found in localStorage"...
that.fail(result.error);
}
};
_1();
}; // end loadDocument
/**
* Load a document from several storages, and send the first retreived
* document.
* @method loadDocument
*/
that.loadDocument = function (command) {
priv.doJob (
command.clone(),
'All load "'+ command.getPath() +'" requests have failed.');
};
/**
* Gets a document list.
* @method getDocumentList
*/
that.getDocumentList = function () {
var new_job, i, l, cpt = 0, array, ok = true,
_1 = function () {
new_job = that.cloneJob();
new_job.storage = that.getSecondStorage();
new_job.callback = getListCallback;
that.addJob ( new_job );
},
getListCallback = function (result) {
if (result.status === 'done') {
array = result.return_value;
for (i = 0, l = array.length; i < l; i+= 1) {
// cpt--;
priv.decrypt (array[i].name,
lastCallback,i,'name');
// priv.decrypt (array[i].content,
// lastCallback,i,'content');
}
} else {
that.fail(result.error);
}
},
lastCallback = function (res,index,key) {
var tmp;
cpt++;
if (typeof res === 'object') {
if (ok) {
that.fail({status:0,statusText:'Decrypt Fail',
message:'Unable to decrypt.'});
}
ok = false;
return;
}
array[index][key] = res;
if (cpt === l && ok) {
// this is the last callback
that.done(array);
}
};
_1();
}; // end getDocumentList
/**
* Get a document list from several storages, and returns the first
* retreived document list.
* @method getDocumentList
*/
that.getDocumentList = function (command) {
priv.doJob (
command.clone(),
'All get document list requests have failed.');
};
/**
* Removes a document.
* @method removeDocument
*/
that.removeDocument = function () {
var new_job, new_file_name,
_1 = function () {
priv.encrypt(that.getFileName(),function(res) {
new_file_name = res;
_2();
});
},
_2 = function () {
new_job = that.cloneJob();
new_job.name = new_file_name;
new_job.storage = that.getSecondStorage();
new_job.callback = removeCallback;
that.addJob(new_job);
},
removeCallback = function (result) {
if (result.status === 'done') {
that.done();
} else {
that.fail(result.error);
}
};
_1();
};
return that;
/**
* Remove a document from several storages.
* @method removeDocument
*/
that.removeDocument = function (command) {
priv.doJob (
command.clone(),
'All remove "' + command.getPath() + '" requests have failed.');
};
// end Crypted Storage
////////////////////////////////////////////////////////////////////////////
// add key to storageObjectType of global jio
Jio.addStorageType('local', newLocalStorage);
Jio.addStorageType('dav', newDAVStorage);
Jio.addStorageType('replicate', newReplicateStorage);
Jio.addStorageType('indexed', newIndexedStorage);
Jio.addStorageType('crypted', newCryptedStorage);
return that;
};
Jio.addStorageType('replicate', newReplicateStorage);
if (window.requirejs) {
define ('JIOStorages',
['LocalOrCookieStorage','jQuery','Base64','SJCL','JIO'],
jioStorageLoader);
} else {
jioStorageLoader ( LocalOrCookieStorage, jQuery, Base64, sjcl, JIO);
}
}());
}( LocalOrCookieStorage, jQuery, Base64, sjcl, jio ));
/*! JIO Storage - v0.1.0 - 2012-06-05
/*! JIO Storage - v0.1.0 - 2012-06-14
* Copyright (c) 2012 Nexedi; Licensed */
(function(){var a=function(a,b,c,d,e){var f,g,h,i,j;f=function(b,c){var d=e.newBaseStorage(b,c),f={};return f.storage_user_array_name="jio/local_user_array",f.storage_file_array_name="jio/local_file_name_array/"+d.getStorageUserName()+"/"+d.getApplicantID(),f.getUserArray=function(){return a.getItem(f.storage_user_array_name)||[]},f.addUser=function(b){var c=f.getUserArray();c.push(b),a.setItem(f.storage_user_array_name,c)},f.userExists=function(a){var b=f.getUserArray(),c,d;for(c=0,d=b.length;c<d;c+=1)if(b[c]===a)return!0;return!1},f.getFileNameArray=function(){return a.getItem(f.storage_file_array_name)||[]},f.addFileName=function(b){var c=f.getFileNameArray();c.push(b),a.setItem(f.storage_file_array_name,c)},f.removeFileName=function(b){var c,d,e=f.getFileNameArray(),g=[];for(c=0,d=e.length;c<d;c+=1)e[c]!==b&&g.push(e[c]);a.setItem(f.storage_file_array_name,g)},d.checkNameAvailability=function(){setTimeout(function(){d.done(!f.userExists(d.getUserName()))},100)},d.saveDocument=function(){setTimeout(function(){var b=null,c="jio/local/"+d.getStorageUserName()+"/"+d.getApplicantID()+"/"+d.getFileName();return b=a.getItem(c),b?(b.last_modified=Date.now(),b.content=d.getFileContent()):(b={name:d.getFileName(),content:d.getFileContent(),creation_date:Date.now(),last_modified:Date.now()},f.userExists(d.getStorageUserName())||f.addUser(d.getStorageUserName()),f.addFileName(d.getFileName())),a.setItem(c,b),d.done()},100)},d.loadDocument=function(){setTimeout(function(){var b=null,c=d.cloneOptionObject();b=a.getItem("jio/local/"+d.getStorageUserName()+"/"+d.getApplicantID()+"/"+d.getFileName()),b?(c.metadata_only?delete b.content:c.content_only&&(delete b.last_modified,delete b.creation_date),d.done(b)):d.fail({status:404,statusText:"Not Found.",message:'Document "'+d.getFileName()+'" not found in localStorage.'})},100)},d.getDocumentList=function(){setTimeout(function(){var b=[],c=[],e,g,h="key",i="jio/local/"+d.getStorageUserName()+"/"+d.getApplicantID(),j={};c=f.getFileNameArray();for(e=0,g=c.length;e<g;e+=1)j=a.getItem(i+"/"+c[e]),j&&b.push({name:j.name,creation_date:j.creation_date,last_modified:j.last_modified});d.done(b)},100)},d.removeDocument=function(){setTimeout(function(){var b="jio/local/"+d.getStorageUserName()+"/"+d.getApplicantID()+"/"+d.getFileName();return a.deleteItem(b),f.removeFileName(d.getFileName()),d.done()},100)},d},g=function(a,d){var f=e.newBaseStorage(a,d);return f.mkcol=function(a){var d=b.extend({success:function(){},error:function(){}},a),e=["split_path"],g="temp/path";if(!d.pathsteps)d.pathsteps=1,f.mkcol(d);else{e=d.path.split("/");if(d.pathsteps>=e.length-1)return d.success();e.length=d.pathsteps+1,d.pathsteps++,g=e.join("/"),b.ajax({url:d.url+g,type:"MKCOL",async:!0,headers:{Authorization:"Basic "+c.encode(d.user_name+":"+d.password),Depth:"1"},success:function(){f.mkcol(d)},error:function(a){d.error()}})}},f.checkNameAvailability=function(){b.ajax({url:f.getStorageURL()+"/dav/"+f.getStorageUserName()+"/",async:!0,type:"PROPFIND",dataType:"xml",headers:{Authorization:"Basic "+c.encode(f.getStorageUserName()+":"+f.getStoragePassword()),Depth:"1"},success:function(a){f.done(!1)},error:function(a){a.status===404?f.done(!0):(a.message='Cannot check availability of "'+f.getUserName()+'" into DAVStorage.',f.fail(a))}})},f.saveDocument=function(){b.ajax({url:f.getStorageURL()+"/dav/"+f.getStorageUserName()+"/"+f.getApplicantID()+"/"+f.getFileName(),type:"PUT",data:f.getFileContent(),async:!0,dataType:"text",headers:{Authorization:"Basic "+c.encode(f.getStorageUserName()+":"+f.getStoragePassword())},success:function(){f.done()},error:function(a){a.message='Cannot save "'+f.getFileName()+'" into DAVStorage.',f.fail(a)}})},f.loadDocument=function(){var a={},d=f.cloneOptionObject(),e=function(){b.ajax({url:f.getStorageURL()+"/dav/"+f.getStorageUserName()+"/"+f.getApplicantID()+"/"+f.getFileName(),type:"GET",async:!0,dataType:"text",headers:{Authorization:"Basic "+c.encode(f.getStorageUserName()+":"+f.getStoragePassword())},success:function(b){a.content=b,f.done(a)},error:function(a){a.status===404?a.message='Document "'+f.getFileName()+'" not found in localStorage.':a.message='Cannot load "'+f.getFileName()+'" from DAVStorage.',f.fail(a)}})};a.name=f.getFileName();if(d.content_only){e();return}b.ajax({url:f.getStorageURL()+"/dav/"+f.getStorageUserName()+"/"+f.getApplicantID()+"/"+f.getFileName(),type:"PROPFIND",async:!0,dataType:"xml",headers:{Authorization:"Basic "+c.encode(f.getStorageUserName()+":"+f.getStoragePassword())},success:function(c){b(c).find("lp1\\:getlastmodified, getlastmodified").each(function(){a.last_modified=b(this).text()}),b(c).find("lp1\\:creationdate, creationdate").each(function(){a.creation_date=b(this).text()}),d.metadata_only?f.done(a):e()},error:function(a){a.message='Cannot load "'+f.getFileName()+'" informations from DAVStorage.',f.fail(a)}})},f.getDocumentList=function(){var a=[],d={},e=[];b.ajax({url:f.getStorageURL()+"/dav/"+f.getStorageUserName()+"/"+f.getApplicantID()+"/",async:!0,type:"PROPFIND",dataType:"xml",headers:{Authorization:"Basic "+c.encode(f.getStorageUserName()+":"+f.getStoragePassword()),Depth:"1"},success:function(c){b(c).find("D\\:response, response").each(function(c,f){if(c>0){d={},b(f).find("D\\:href, href").each(function(){e=b(this).text().split("/"),d.name=e[e.length-1]?e[e.length-1]:e[e.length-2]+"/"});if(d.name===".htaccess"||d.name===".htpasswd")return;b(f).find("lp1\\:getlastmodified, getlastmodified").each(function(){d.last_modified=b(this).text()}),b(f).find("lp1\\:creationdate, creationdate").each(function(){d.creation_date=b(this).text()}),a.push(d)}}),f.done(a)},error:function(a){a.message="Cannot get a document list from DAVStorage.",f.fail(a)}})},f.removeDocument=function(){b.ajax({url:f.getStorageURL()+"/dav/"+f.getStorageUserName()+"/"+f.getApplicantID()+"/"+f.getFileName(),type:"DELETE",async:!0,headers:{Authorization:"Basic "+c.encode(f.getStorageUserName()+":"+f.getStoragePassword())},success:function(){f.done()},error:function(a){a.status===404?f.done():(a.message='Cannot remove "'+f.getFileName()+'" from DAVStorage.',f.fail(a))}})},f},h=function(a,b){var c=e.newBaseStorage(a,b),d={};return d.storageArray=c.getStorageArray(),d.length=d.storageArray.length,d.return_value_array=[],d.max_tries=c.getMaxTries(),c.setMaxTries(1),d.execJobsFromStorageArray=function(a){var b={},e;for(e=0;e<d.storageArray.length;e+=1)b=c.cloneJob(),b.max_tries=d.max_tries,b.storage=d.storageArray[e],b.callback=a,c.addJob(b)},c.checkNameAvailability=function(){var a="id",b=!1,e=[],f={status:"done"},g=function(a){d.return_value_array.push(a);if(!b){if(a.status==="fail")f.status="fail",e.push(a.error);else if(a.return_value===!1){c.done(!1),b=!0;return}if(d.return_value_array.length===d.length){f.status==="fail"?c.fail({status:207,statusText:"Multi-Status",message:'Some check availability of "'+c.getUserName()+'" requests have failed.',array:e}):c.done(!0),b=!0;return}}};d.execJobsFromStorageArray(g)},c.saveDocument=function(){var a={status:"done"},b="id",e=!1,f=[],g=function(a){d.return_value_array.push(a),e||(a.status!=="fail"?(c.done(),e=!0):(f.push(a.error),d.return_value_array.length===d.length&&c.fail({status:207,statusText:"Multi-Status",message:'All save "'+c.getFileName()+'" requests have failed.',array:f})))};d.execJobsFromStorageArray(g)},c.loadDocument=function(){var a={},b="id",e=!1,f=[],g={status:"done"},h=function(a){d.return_value_array.push(a),e||(a.status!=="fail"?(c.done(a.return_value),e=!0):(f.push(a.error),d.return_value_array.length===d.length&&c.fail({status:207,statusText:"Multi-Status",message:'All load "'+c.getFileName()+'" requests have failed.',array:f})))};d.execJobsFromStorageArray(h)},c.getDocumentList=function(){var a={status:"done"},b="id",e=!1,f=[],g=function(a){d.return_value_array.push(a),e||(a.status!=="fail"?(c.done(a.return_value),e=!0):(f.push(a.error),d.return_value_array.length===d.length&&c.fail({status:207,statusText:"Multi-Status",message:"All get document list requests have failed",array:f})))};d.execJobsFromStorageArray(g)},c.removeDocument=function(){var a={status:"done"},b="key",e=!1,f=[],g=function(a){d.return_value_array.push(a),e||(a.status!=="fail"?(c.done(),e=!0):(f.push(a.error),d.return_value_array.length===d.length&&c.fail({status:207,statusText:"Multi-Status",message:'All remove "'+c.getFileName()+'" requests have failed.',array:f})))};d.execJobsFromStorageArray(g)},c},i=function(b,c){var d=e.newBaseStorage(b,c),f={};return f.storage_array_name="jio/indexed_storage_array",f.storage_file_array_name="jio/indexed_file_array/"+JSON.stringify(d.getSecondStorage())+"/"+d.getApplicantID(),f.indexedStorageArrayExists=function(){return a.getItem(f.storage_array_name)?!0:!1},f.getIndexedStorageArray=function(){return a.getItem(f.storage_array_name)||[]},f.addIndexedStorage=function(b){var c=f.getIndexedStorageArray();c.push(JSON.stringify(b)),a.setItem(f.storage_array_name,c)},f.isAnIndexedStorage=function(a){var b=JSON.stringify(a),c,d,e=f.getIndexedStorageArray();for(c=0,d=e.length;c<d;c+=1)if(JSON.stringify(e[c])===b)return!0;return!1},f.fileArrayExists=function(){return a.getItem(f.storage_file_array_name)?!0:!1},f.getFileArray=function(){return a.getItem(f.storage_file_array_name)||[]},f.setFileArray=function(b){return a.setItem(f.storage_file_array_name,b)},f.isFileIndexed=function(a){var b,c,d=f.getFileArray();for(b=0,c=d.length;b<c;b+=1)if(d[b].name===a)return!0;return!1},f.addFile=function(b){var c=f.getFileArray();c.push(b),a.setItem(f.storage_file_array_name,c)},f.removeFile=function(b){var c,d,e=f.getFileArray(),g=[];for(c=0,d=e.length;c<d;c+=1)e[c].name!==b&&g.push(e[c]);a.setItem(f.storage_file_array_name,g)},f.update=function(a){var b=function(a){a.status==="done"&&(f.isAnIndexedStorage(d.getSecondStorage())||f.addIndexedStorage(d.getSecondStorage()),f.setFileArray(a.return_value))},c={storage:d.getSecondStorage(),applicant:{ID:d.getApplicantID()},method:"getDocumentList",max_tries:3,callback:b};d.addJob(c)},d.checkNameAvailability=function(){var a=d.cloneJob();f.update(),a.storage=d.getSecondStorage(),a.callback=function(a){a.status==="done"?d.done(a.return_value):d.fail(a.error)},d.addJob(a)},d.saveDocument=function(){var a=d.cloneJob();a.storage=d.getSecondStorage(),a.callback=function(a){a.status==="done"?(f.isFileIndexed(d.getFileName())||f.addFile({name:d.getFileName(),last_modified:0,creation_date:0}),f.update(),d.done()):d.fail(a.error)},d.addJob(a)},d.loadDocument=function(){var a,b,c,e,g=function(a){a.status==="done"?d.done(a.return_value):d.fail(a.error)},h=function(){e=d.cloneJob(),e.storage=d.getSecondStorage(),e.callback=g,d.addJob(e)},i=d.cloneOptionObject();f.update(),i.metadata_only?setTimeout(function(){if(f.fileArrayExists()){a=f.getFileArray();for(b=0,c=a.length;b<c;b+=1)if(a[b].name===d.getFileName())return d.done(a[b])}else h()},100):h()},d.getDocumentList=function(){var a;f.update(),a=setInterval(function(){f.fileArrayExists()&&(d.done(f.getFileArray()),clearInterval(a))},100)},d.removeDocument=function(){var a=d.cloneJob();a.storage=d.getSecondStorage(),a.callback=function(a){a.status==="done"?(f.removeFile(d.getFileName()),f.update(),d.done()):d.fail(a.error)},d.addJob(a)},d},j=function(a,c){var f=e.newBaseStorage(a,c),g={};return g.encrypt_param_object={iv:"kaprWwY/Ucr7pumXoTHbpA",v:1,iter:1e3,ks:256,ts:128,mode:"ccm",adata:"",cipher:"aes",salt:"K4bmZG9d704"},g.decrypt_param_object={iv:"kaprWwY/Ucr7pumXoTHbpA",ks:256,ts:128,salt:"K4bmZG9d704"},g.encrypt=function(a,b,c){var e=d.encrypt(f.getStorageUserName()+":"+f.getStoragePassword(),a,g.encrypt_param_object);b(JSON.parse(e).ct,c)},g.decrypt=function(a,c,e,h){var i,j=b.extend(!0,{},g.decrypt_param_object);j.ct=a||"",j=JSON.stringify(j);try{i=d.decrypt(f.getStorageUserName()+":"+f.getStoragePassword(),j)}catch(k){c({status:0,statusText:"Decrypt Fail",message:"Unable to decrypt."},e,h);return}c(i,e,h)},f.checkNameAvailability=function(){var a=f.cloneJob();a.storage=f.getSecondStorage(),a.callback=function(a){a.status==="done"?f.done(a.return_value):f.fail(a.error)},f.addJob(a)},f.saveDocument=function(){var a,b,c,d=function(){g.encrypt(f.getFileName(),function(a){b=a,e()})},e=function(){g.encrypt(f.getFileContent(),function(a){c=a,h()})},h=function(){a=f.cloneJob(),a.name=b,a.content=c,a.storage=f.getSecondStorage(),a.callback=function(a){a.status==="done"?f.done():f.fail(a.error)},f.addJob(a)};d()},f.loadDocument=function(){var a,b,c=f.cloneOptionObject(),d=function(){g.encrypt(f.getFileName(),function(a){b=a,e()})},e=function(){a=f.cloneJob(),a.name=b,a.storage=f.getSecondStorage(),a.callback=h,f.addJob(a)},h=function(a){a.status==="done"?(a.return_value.name=f.getFileName(),c.metadata_only?f.done(a.return_value):g.decrypt(a.return_value.content,function(b){typeof b=="object"?f.fail({status:0,statusText:"Decrypt Fail",message:"Unable to decrypt"}):(a.return_value.content=b,f.done(a.return_value))})):f.fail(a.error)};d()},f.getDocumentList=function(){var a,b,c,d=0,e,h=!0,i=function(){a=f.cloneJob(),a.storage=f.getSecondStorage(),a.callback=j,f.addJob(a)},j=function(a){if(a.status==="done"){e=a.return_value;for(b=0,c=e.length;b<c;b+=1)g.decrypt(e[b].name,k,b,"name")}else f.fail(a.error)},k=function(a,b,g){var i;d++;if(typeof a=="object"){h&&f.fail({status:0,statusText:"Decrypt Fail",message:"Unable to decrypt."}),h=!1;return}e[b][g]=a,d===c&&h&&f.done(e)};i()},f.removeDocument=function(){var a,b,c=function(){g.encrypt(f.getFileName(),function(a){b=a,d()})},d=function(){a=f.cloneJob(),a.name=b,a.storage=f.getSecondStorage(),a.callback=e,f.addJob(a)},e=function(a){a.status==="done"?f.done():f.fail(a.error)};c()},f},e.addStorageType("local",f),e.addStorageType("dav",g),e.addStorageType("replicate",h),e.addStorageType("indexed",i),e.addStorageType("crypted",j)};window.requirejs?define("JIOStorages",["LocalOrCookieStorage","jQuery","Base64","SJCL","JIO"],a):a(LocalOrCookieStorage,jQuery,Base64,sjcl,JIO)})();
\ No newline at end of file
(function(a,b,c,d,e){var f=function(b,c){var d=e.storage(b,c,"base"),f={};f.username=b.username||"",f.applicationname=b.applicationname||"untitled";var g="jio/local_user_array",h="jio/local_file_name_array/"+f.username+"/"+f.applicationname,i=d.serialized;return d.serialized=function(){var a=i();return a.applicationname=f.applicationname,a.username=f.username,a},d.validateState=function(){return f.username?"":'Need at least one parameter: "username".'},f.getUserArray=function(){return a.getItem(g)||[]},f.addUser=function(b){var c=f.getUserArray();c.push(b),a.setItem(g,c)},f.userExists=function(a){var b=f.getUserArray(),c,d;for(c=0,d=b.length;c<d;c+=1)if(b[c]===a)return!0;return!1},f.getFileNameArray=function(){return a.getItem(h)||[]},f.addFileName=function(b){var c=f.getFileNameArray();c.push(b),a.setItem(h,c)},f.removeFileName=function(b){var c,d,e=f.getFileNameArray(),g=[];for(c=0,d=e.length;c<d;c+=1)e[c]!==b&&g.push(e[c]);a.setItem(h,g)},d.saveDocument=function(b){setTimeout(function(){var c=null,e="jio/local/"+f.username+"/"+f.applicationname+"/"+b.getPath();c=a.getItem(e),c?(c.last_modified=Date.now(),c.content=b.getContent()):(c={name:b.getPath(),content:b.getContent(),creation_date:Date.now(),last_modified:Date.now()},f.userExists(f.username)||f.addUser(f.username),f.addFileName(b.getPath())),a.setItem(e,c),d.done()},100)},d.loadDocument=function(b){setTimeout(function(){var c=null;c=a.getItem("jio/local/"+f.username+"/"+f.applicationname+"/"+b.getPath()),c?(b.getOption("metadata_only")&&delete c.content,d.done(c)):d.fail(b,{status:404,statusText:"Not Found.",message:'Document "'+b.getPath()+'" not found in localStorage.'})},100)},d.getDocumentList=function(b){setTimeout(function(){var c=[],e=[],g,h,i="key",j="jio/local/"+f.username+"/"+f.applicationname,k={};e=f.getFileNameArray();for(g=0,h=e.length;g<h;g+=1)k=a.getItem(j+"/"+e[g]),k&&(b.getOption("metadata_only")?c.push({name:k.name,creation_date:k.creation_date,last_modified:k.last_modified}):c.push({name:k.name,content:k.content,creation_date:k.creation_date,last_modified:k.last_modified}));d.done(c)},100)},d.removeDocument=function(b){setTimeout(function(){var c="jio/local/"+f.username+"/"+f.applicationname+"/"+b.getPath();a.deleteItem(c),f.removeFileName(b.getPath()),d.done()},100)},d};e.addStorageType("local",f);var g=function(a,d){var f=e.storage(a,d,"base"),g={};g.username=a.username||"",g.applicationname=a.applicationname||"untitled",g.url=a.url||"",g.password=a.password||"";var h=f.serialized;return f.serialized=function(){var a=h();return a.username=g.username,a.applicationname=g.applicationname,a.url=g.url,a.password=g.password,a},f.validateState=function(){return g.username&&g.url?"":'Need at least 2 parameters: "username" and "url".'},f.saveDocument=function(a){b.ajax({url:g.url+"/dav/"+g.username+"/"+g.applicationname+"/"+a.getPath(),type:"PUT",data:a.getContent(),async:!0,dataType:"text",headers:{Authorization:"Basic "+c.encode(g.username+":"+g.password)},success:function(){f.done()},error:function(b){b.message='Cannot save "'+a.getPath()+'" into DAVStorage.',f.fail(b)}})},f.loadDocument=function(a){var d={},e=function(){b.ajax({url:g.url+"/dav/"+g.username+"/"+g.applicationname+"/"+a.getPath(),type:"GET",async:!0,dataType:"text",headers:{Authorization:"Basic "+c.encode(g.username+":"+g.password)},success:function(a){d.content=a,f.done(d)},error:function(b){b.status===404?b.message='Document "'+a.getPath()+'" not found in localStorage.':b.message='Cannot load "'+a.getPath()+'" from DAVStorage.',f.fail(b)}})};d.name=a.getPath(),b.ajax({url:g.url+"/dav/"+g.username+"/"+g.applicationname+"/"+a.getPath(),type:"PROPFIND",async:!0,dataType:"xml",headers:{Authorization:"Basic "+c.encode(g.username+":"+g.password)},success:function(c){b(c).find("lp1\\:getlastmodified, getlastmodified").each(function(){d.last_modified=b(this).text()}),b(c).find("lp1\\:creationdate, creationdate").each(function(){d.creation_date=b(this).text()}),a.getOption("metadata_only")?f.done(d):e()},error:function(b){b.message='Cannot load "'+a.getPath()+'" informations from DAVStorage.',f.fail(b)}})},f.getDocumentList=function(a){var d=[],e={},h=[];b.ajax({url:g.url+"/dav/"+g.username+"/"+g.applicationname+"/",async:!0,type:"PROPFIND",dataType:"xml",headers:{Authorization:"Basic "+c.encode(g.username+":"+g.password),Depth:"1"},success:function(a){b(a).find("D\\:response, response").each(function(a,c){if(a>0){e={},b(c).find("D\\:href, href").each(function(){h=b(this).text().split("/"),e.name=h[h.length-1]?h[h.length-1]:h[h.length-2]+"/"});if(e.name===".htaccess"||e.name===".htpasswd")return;b(c).find("lp1\\:getlastmodified, getlastmodified").each(function(){e.last_modified=b(this).text()}),b(c).find("lp1\\:creationdate, creationdate").each(function(){e.creation_date=b(this).text()}),d.push(e)}}),f.done(d)},error:function(a){a.message="Cannot get a document list from DAVStorage.",f.fail(a)}})},f.removeDocument=function(a){b.ajax({url:g.url+"/dav/"+g.username+"/"+g.applicationname+"/"+a.getPath(),type:"DELETE",async:!0,headers:{Authorization:"Basic "+c.encode(g.username+":"+g.password)},success:function(){f.done()},error:function(a){a.status===404?f.done():(a.message='Cannot remove "'+f.getFileName()+'" from DAVStorage.',f.fail(a))}})},f};e.addStorageType("dav",g);var h=function(a,b){var c=e.storage(a,b,"handler"),d={};return d.return_value_array=[],d.storagelist=a.storagelist||[],d.nb_storage=d.storagelist.length,d.isTheLast=function(){return d.return_value_array.length===d.nb_storage},d.doJob=function(a,f){var g=!1,h=[],i,j=function(a){console.log("respond"),d.return_value_array.push(a)},k=function(a){g||(console.log("fail"),h.push(a),d.isTheLast()&&c.fail({status:207,statusText:"Multi-Status",message:f,array:h}))},l=function(a){g||(console.log("done"),g=!0,c.done(a))};a.setMaxRetry(1);for(i=0;i<d.nb_storage;i+=1){var m=a.clone(),n=e.storage(d.storagelist[i],b);m.onResponseDo(j),m.onFailDo(k),m.onDoneDo(l),c.addJob(n,m)}},c.saveDocument=function(a){d.doJob(a.clone(),'All save "'+a.getPath()+'" requests have failed.')},c.loadDocument=function(a){d.doJob(a.clone(),'All load "'+a.getPath()+'" requests have failed.')},c.getDocumentList=function(a){d.doJob(a.clone(),"All get document list requests have failed.")},c.removeDocument=function(a){d.doJob(a.clone(),'All remove "'+a.getPath()+'" requests have failed.')},c};e.addStorageType("replicate",h)})(LocalOrCookieStorage,jQuery,Base64,sjcl,jio);
\ No newline at end of file
......@@ -16,7 +16,7 @@
// Tells us that the document is saved.
setTimeout (function () {
command.done();
that.done();
}, 100);
}; // end saveDocument
......@@ -30,7 +30,7 @@
'content': 'content',
'creation_date': 10000,
'last_modified': 15000};
command.done(doc);
that.done(doc);
}, 100);
}; // end loadDocument
......@@ -53,7 +53,7 @@
delete list[0].content;
delete list[1].content;
}
command.done(list);
that.done(list);
}, 100);
}; // end getDocumentList
......@@ -61,7 +61,7 @@
// Remove a document from the storage.
setTimeout (function () {
command.done();
that.done();
}, 100);
};
return that;
......@@ -80,7 +80,7 @@
// Tells us that the document is not saved.
setTimeout (function () {
command.fail({status:0,statusText:'Unknown Error',
that.fail({status:0,statusText:'Unknown Error',
message:'Unknown error.'});
}, 100);
}; // end saveDocument
......@@ -89,7 +89,7 @@
// Returns a document object containing nothing.
setTimeout(function () {
command.fail({status:0,statusText:'Unknown Error',
that.fail({status:0,statusText:'Unknown Error',
message:'Unknown error.'});
}, 100);
}; // end loadDocument
......@@ -98,7 +98,7 @@
// It returns nothing.
setTimeout(function () {
command.fail({status:0,statusText:'Unknown Error',
that.fail({status:0,statusText:'Unknown Error',
message:'Unknown error.'});
}, 100);
}; // end getDocumentList
......@@ -107,7 +107,7 @@
// Remove a document from the storage.
setTimeout (function () {
command.fail({status:0,statusText:'Unknown Error',
that.fail({status:0,statusText:'Unknown Error',
message:'Unknown error.'});
}, 100);
};
......@@ -127,7 +127,7 @@
// Document does not exists yet, create it.
setTimeout (function () {
command.done();
that.done();
}, 100);
}; // end saveDocument
......@@ -135,7 +135,7 @@
// Returns a document object containing nothing.
setTimeout(function () {
command.fail({status:404,statusText:'Not Found',
that.fail({status:404,statusText:'Not Found',
message:'Document "'+ command.getPath() +
'" not found.'});
}, 100);
......@@ -145,7 +145,7 @@
// It returns nothing.
setTimeout(function () {
command.fail({status:404,statusText:'Not Found',
that.fail({status:404,statusText:'Not Found',
message:'User list not found.'});
}, 100);
}; // end getDocumentList
......@@ -154,7 +154,7 @@
// Remove a document from the storage.
setTimeout (function () {
command.done();
that.done();
}, 100);
};
return that;
......@@ -169,33 +169,31 @@
that.setType('dummyall3tries');
priv.doJob = function (if_ok_return) {
priv.doJob = function (command,if_ok_return) {
// wait a little in order to simulate asynchronous operation
setTimeout(function () {
priv.Try3OKElseFail (priv.command.getTried(),if_ok_return);
priv.Try3OKElseFail (command.getTried(),if_ok_return);
}, 100);
};
priv.Try3OKElseFail = function (tries,if_ok_return) {
if ( tries === 3 ) {
return priv.command.done(if_ok_return);
return that.done(if_ok_return);
}
if ( tries < 3 ) {
return priv.command.fail(
return that.fail(
{message:'' + (3 - tries) + ' tries left.'});
}
if ( tries > 3 ) {
return priv.command.fail({message:'Too much tries.'});
return that.fail({message:'Too much tries.'});
}
};
that.saveDocument = function (command) {
priv.command = command;
priv.doJob ();
priv.doJob (command);
}; // end saveDocument
that.loadDocument = function (command) {
priv.command = command;
priv.doJob ({
priv.doJob (command,{
'content': 'content2',
'name': 'file',
'creation_date': 11000,
......@@ -204,19 +202,17 @@
}; // end loadDocument
that.getDocumentList = function (command) {
priv.command = command;
priv.doJob([{'name':'file',
'creation_date':10000,
'last_modified':15000},
{'name':'memo',
'creation_date':20000,
'last_modified':25000}
]);
priv.doJob(command,[{'name':'file',
'creation_date':10000,
'last_modified':15000},
{'name':'memo',
'creation_date':20000,
'last_modified':25000}
]);
}; // end getDocumentList
that.removeDocument = function (command) {
priv.command = command;
priv.doJob();
priv.doJob(command);
}; // end removeDocument
return that;
......
......@@ -7,19 +7,49 @@ var activityUpdater = (function(spec, my) {
priv.id = spec.id || 0;
priv.interval = 400;
priv.interval_id = null;
// Methods //
/**
* Update the last activity date in the localStorage.
* @method touch
*/
priv.touch = function() {
LocalOrCookieStorage.setItem ('jio/id/'+priv.id, Date.now());
};
/**
* Sets the jio id into the activity.
* @method setId
* @param {number} id The jio id.
*/
that.setId = function(id) {
priv.id = id;
};
/**
* Sets the interval delay between two updates.
* @method setIntervalDelay
* @param {number} ms In milliseconds
*/
that.setIntervalDelay = function(ms) {
priv.interval = ms;
};
/**
* Gets the interval delay.
* @method getIntervalDelay
* @return {number} The interval delay.
*/
that.getIntervalDelay = function() {
return priv.interval;
};
/**
* Starts the activity updater. It will update regulary the last activity
* date in the localStorage to show to other jio instance that this instance
* is active.
* @method start
*/
that.start = function() {
if (!priv.interval_id) {
priv.touch();
......@@ -28,12 +58,18 @@ var activityUpdater = (function(spec, my) {
}, priv.interval);
}
};
/**
* Stops the activity updater.
* @method stop
*/
that.stop = function() {
if (priv.interval_id !== null) {
clearInterval(priv.interval_id);
priv.interval_id = null;
}
};
return that;
}());
......@@ -5,6 +5,7 @@ var announcement = function(spec, my) {
// Attributes //
var callback_a = [];
var name = spec.name || '';
var announcer = spec.announcer || {};
// Methods //
that.add = function(callback) {
callback_a.push(callback);
......
......@@ -103,8 +103,8 @@ var command = function(spec, my) {
};
that.done = function(return_value) {
priv.done(return_value);
priv.respond({status:doneStatus(),value:return_value});
priv.done(return_value);
priv.end();
};
......@@ -112,17 +112,29 @@ var command = function(spec, my) {
if (priv.option.max_retry === 0 || priv.tried < priv.option.max_retry) {
priv.retry();
} else {
priv.fail(return_error);
priv.respond({status:failStatus(),error:return_error});
priv.fail(return_error);
priv.end();
}
};
that.onEndDo = function(fun) {
that.onResponseDo = function (fun) {
priv.respond = fun;
};
that.onDoneDo = function (fun) {
priv.done = fun;
};
that.onFailDo = function (fun) {
priv.fail = fun;
};
that.onEndDo = function (fun) {
priv.end = fun;
};
that.onRetryDo = function(fun) {
that.onRetryDo = function (fun) {
priv.retry = fun;
};
......@@ -144,5 +156,9 @@ var command = function(spec, my) {
return true;
};
that.clone = function () {
return command(that.serialized(), my);
};
return that;
};
......@@ -16,5 +16,23 @@ var getDocumentList = function(spec, my) {
return false;
};
var super_done = that.done;
that.done = function (res) {
var i;
if (res) {
for (i = 0; i < res.length; i+= 1) {
if (typeof res[i].last_modified !== 'number') {
res[i].last_modified =
new Date(res[i].last_modified).getTime();
}
if (typeof res[i].creation_date !== 'number') {
res[i].creation_date =
new Date(res[i].creation_date).getTime();
}
}
}
super_done(res);
};
return that;
};
......@@ -16,5 +16,17 @@ var loadDocument = function(spec, my) {
return false;
};
var super_done = that.done;
that.done = function (res) {
if (res) {
if (typeof res.last_modified !== 'number') {
res.last_modified=new Date(res.last_modified).getTime();
}
if (typeof res.creation_date !== 'number') {
res.creation_date=new Date(res.creation_date).getTime();
}
}
super_done(res);
};
return that;
};
......@@ -6,7 +6,11 @@
var priv = {};
var jio_id_array_name = 'jio/id_array';
priv.id = null;
priv.storage = jioNamespace.storage(spec);
my.jobManager = jobManager;
my.jobIdHandler = jobIdHandler;
priv.storage = jioNamespace.storage(spec, my);
// initialize //
priv.init = function() {
......@@ -68,7 +72,7 @@
* @return {boolean} true if ok, else false.
*/
that.validateStorageDescription = function(description) {
return jioNamespace.storage(description.type)(description).isValid();
return jioNamespace.storage(description, my).isValid();
};
/**
......@@ -92,10 +96,10 @@
option.max_retry = option.max_retry || 0;
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:saveDocument(
{path:path,content:content,option:option})}));
{path:path,content:content,option:option})},my));
};
/**
......@@ -121,10 +125,10 @@
option.metadata_only:false);
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:loadDocument(
{path:path,option:option})}));
{path:path,option:option})},my));
};
/**
......@@ -147,10 +151,10 @@
option.max_retry = option.max_retry || 0;
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:removeDocument(
{path:path,option:option})}));
{path:path,option:option})},my));
};
/**
......@@ -176,10 +180,10 @@
option.metadata_only:true);
jobManager.addJob(
job({storage:(specificstorage?
jioNamespace.storage(specificstorage):
jioNamespace.storage(specificstorage,my):
priv.storage),
command:getDocumentList(
{path:path,option:option})}));
{path:path,option:option})},my));
};
return that;
......
......@@ -3,7 +3,10 @@ var jioNamespace = (function(spec, my) {
spec = spec || {};
my = my || {};
// Attributes //
var storage_type_o = {'base':storage,'handler':storageHandler};
var storage_type_o = { // -> 'key':constructorFunction
'base': storage,
'handler': storageHandler
};
// Methods //
......
......@@ -4,7 +4,7 @@ var job = function(spec, my) {
my = my || {};
// Attributes //
var priv = {};
priv.id = jobIdHandler.nextId();
priv.id = my.jobIdHandler.nextId();
priv.command = spec.command;
priv.storage = spec.storage;
priv.status = initialStatus();
......@@ -78,7 +78,7 @@ var job = function(spec, my) {
*/
that.waitForJob = function(job) {
if (priv.status.getLabel() !== 'wait') {
priv.status = waitStatus();
priv.status = waitStatus({},my);
}
priv.status.waitForJob(job);
};
......@@ -101,7 +101,7 @@ var job = function(spec, my) {
*/
that.waitForTime = function(ms) {
if (priv.status.getLabel() !== 'wait') {
priv.status = waitStatus();
priv.status = waitStatus({},my);
}
priv.status.waitForTime(ms);
};
......@@ -148,7 +148,7 @@ var job = function(spec, my) {
that.waitForTime(ms);
});
priv.command.onEndDo (function() {
jobManager.terminateJob (that);
my.jobManager.terminateJob (that);
});
priv.command.execute (priv.storage);
};
......
......@@ -10,13 +10,32 @@ var jobManager = (function(spec, my) {
priv.interval = 200;
priv.job_a = [];
my.jobManager = that;
my.jobIdHandler = that;
// Methods //
/**
* Get the job array name in the localStorage
* @method getJobArrayName
* @return {string} The job array name
*/
priv.getJobArrayName = function() {
return job_array_name + '/' + priv.id;
};
/**
* Returns the job array from the localStorage
* @method getJobArray
* @return {array} The job array.
*/
priv.getJobArray = function() {
return LocalOrCookieStorage.getItem(priv.getJobArrayName())||[];
};
/**
* Does a backup of the job array in the localStorage.
* @method copyJobArrayToLocal
*/
priv.copyJobArrayToLocal = function() {
var new_a = [], i;
for (i = 0; i < priv.job_a.length; i+= 1) {
......@@ -25,6 +44,11 @@ var jobManager = (function(spec, my) {
LocalOrCookieStorage.setItem(priv.getJobArrayName(),new_a);
};
/**
* Removes a job from the current job array.
* @method removeJob
* @param {object} job The job object.
*/
priv.removeJob = function(job) {
var i, tmp_job_a = [];
for (i = 0; i < priv.job_a.length; i+= 1) {
......@@ -75,6 +99,12 @@ var jobManager = (function(spec, my) {
}
};
/**
* Try to restore an the inactive older jio instances.
* It will restore the on going or initial jobs from their job array
* and it will add them to this job array.
* @method restoreOldJio
*/
priv.restoreOldJio = function() {
var i, jio_id_a;
priv.lastrestore = priv.lastrestore || 0;
......@@ -86,6 +116,11 @@ var jobManager = (function(spec, my) {
priv.lastrestore = Date.now();
};
/**
* Try to restore an old jio according to an id.
* @method restoreOldJioId
* @param {number} id The jio id.
*/
priv.restoreOldJioId = function(id) {
var jio_date;
jio_date = LocalOrCookieStorage.getItem('jio/id/'+id)||0;
......@@ -96,19 +131,29 @@ var jobManager = (function(spec, my) {
}
};
/**
* Try to restore all jobs from another jio according to an id.
* @method restoreOldJobFromJioId
* @param {number} id The jio id.
*/
priv.restoreOldJobFromJioId = function(id) {
var i, jio_job_array;
jio_job_array = LocalOrCookieStorage.getItem('jio/job_array/'+id)||[];
for (i = 0; i < jio_job_array.length; i+= 1) {
var command_o = command(jio_job_array[i].command);
var command_o = command(jio_job_array[i].command, my);
if (command_o.canBeRestored()) {
that.addJob ( job(
{storage:jioNamespace.storage(jio_job_array[i].storage),
command:command_o}));
{storage:jioNamespace.storage(jio_job_array[i].storage,my),
command:command_o}, my));
}
}
};
/**
* Removes a jio instance according to an id.
* @method removeOldJioId
* @param {number} id The jio id.
*/
priv.removeOldJioId = function(id) {
var i, jio_id_a, new_a = [];
jio_id_a = LocalOrCookieStorage.getItem('jio/id_array')||[];
......@@ -121,6 +166,11 @@ var jobManager = (function(spec, my) {
LocalOrCookieStorage.deleteItem('jio/id/'+id);
};
/**
* Removes a job array from a jio instance according to an id.
* @method removeJobArrayFromJioId
* @param {number} id The jio id.
*/
priv.removeJobArrayFromJioId = function(id) {
LocalOrCookieStorage.deleteItem('jio/job_array/'+id);
};
......@@ -143,6 +193,12 @@ var jobManager = (function(spec, my) {
priv.copyJobArrayToLocal();
};
/**
* Checks if a job exists in the job array according to a job id.
* @method jobIdExists
* @param {number} id The job id.
* @return {boolean} true if exists, else false.
*/
that.jobIdExists = function(id) {
var i;
for (i = 0; i < priv.job_a.length; i+= 1) {
......@@ -153,16 +209,32 @@ var jobManager = (function(spec, my) {
return false;
};
/**
* Terminate a job. It only remove it from the job array.
* @method terminateJob
* @param {object} job The job object
*/
that.terminateJob = function(job) {
priv.removeJob(job);
priv.copyJobArrayToLocal();
};
/**
* Adds a job to the current job array.
* @method addJob
* @param {object} job The new job.
*/
that.addJob = function(job) {
var result_a = that.validateJobAccordingToJobList (priv.job_a,job);
priv.manage (job,result_a);
priv.appendJob (job,result_a);
};
/**
* Generate a result array containing action string to do with the good job.
* @method validateJobAccordingToJobList
* @param {array} job_a A job array.
* @param {object} job The new job to compare with.
* @return {array} A result array.
*/
that.validateJobAccordingToJobList = function(job_a,job) {
var i, result_a = [];
for (i = 0; i < job_a.length; i+= 1) {
......@@ -171,7 +243,16 @@ var jobManager = (function(spec, my) {
return result_a;
};
priv.manage = function(job,result_a) {
/**
* It will manage the job in order to know what to do thanks to a result
* array. The new job can be added to the job array, but it can also be
* not accepted. It is this method which can tells jobs to wait for another
* one, to replace one or to eliminate some while browsing.
* @method appendJob
* @param {object} job The job to append.
* @param {array} result_a The result array.
*/
priv.appendJob = function(job,result_a) {
var i;
if (priv.job_a.length !== result_a.length) {
throw new RangeError("Array out of bound");
......@@ -184,7 +265,7 @@ var jobManager = (function(spec, my) {
for (i = 0; i < result_a.length; i+= 1) {
switch (result_a[i].action) {
case 'eliminate':
that.eliminate(result_a[i].job);
priv.removeJob(result_a[i].job);
break;
case 'update':
result_a[i].job.update(job);
......@@ -200,16 +281,5 @@ var jobManager = (function(spec, my) {
priv.copyJobArrayToLocal();
};
that.eliminate = function(job) {
var i, tmp_a = [];
for (i = 0; i < priv.job_a.length; i+= 1) {
if (priv.job_a[i].getId() !== job.getId()) {
tmp_a.push(priv.job_a[i]);
}
}
priv.job_a = tmp_a;
priv.copyJobArrayToLocal();
};
return that;
}());
......@@ -18,6 +18,13 @@ var jobRules = (function(spec, my) {
};
// Methods //
/**
* Returns an action according the jobs given in parameters.
* @method getAction
* @param {object} job1 The already existant job.
* @param {object} job2 The job to compare with.
* @return {string} An action string.
*/
priv.getAction = function(job1,job2) {
var j1label, j2label, j1status;
j1label = job1.getCommand().getLabel();
......@@ -32,6 +39,14 @@ var jobRules = (function(spec, my) {
return that.default_action(job1,job2);
}
};
/**
* Checks if the two jobs are comparable.
* @method canCompare
* @param {object} job1 The already existant job.
* @param {object} job2 The job to compare with.
* @return {boolean} true if comparable, else false.
*/
priv.canCompare = function(job1,job2) {
var job1label = job1.getCommand().getLabel(),
job2label = job2.getCommand().getLabel();
......@@ -85,6 +100,8 @@ var jobRules = (function(spec, my) {
priv.compare[method1][method2] = rule;
};
////////////////////////////////////////////////////////////////////////////
// Adding some rules
/*
LEGEND:
- s: storage
......@@ -165,5 +182,7 @@ var jobRules = (function(spec, my) {
that.addActionRule('getDocumentList',true ,'getDocumentList',that.dontAccept);
that.addActionRule('getDocumentList',false,'getDocumentList',that.update);
// end adding rules
////////////////////////////////////////////////////////////////////////////
return that;
}());
......@@ -14,5 +14,10 @@ var jobStatus = function(spec, my) {
that.serialized = function() {
return {label:that.getLabel()};
};
that.isWaitStatus = function() {
return false;
};
return that;
};
\ No newline at end of file
};
......@@ -6,21 +6,36 @@ var waitStatus = function(spec, my) {
var priv = {};
priv.job_id_a = spec.job_id_array || [];
priv.threshold = 0;
// Methods //
/**
* Returns the label of this status.
* @method getLabel
* @return {string} The label: 'wait'.
*/
that.getLabel = function() {
return 'wait';
};
/**
* Refresh the job id array to wait.
* @method refreshJobIdArray
*/
priv.refreshJobIdArray = function() {
var tmp_job_id_a = [], i;
for (i = 0; i < priv.job_id_a.length; i+= 1) {
if (jobManager.jobIdExists(priv.job_id_a[i])) {
if (my.jobManager.jobIdExists(priv.job_id_a[i])) {
tmp_job_id_a.push(priv.job_id_a[i]);
}
}
priv.job_id_a = tmp_job_id_a;
};
/**
* The status must wait for the job end before start again.
* @method waitForJob
* @param {object} job The job to wait for.
*/
that.waitForJob = function(job) {
var i;
for (i = 0; i < priv.job_id_a.length; i+= 1) {
......@@ -30,6 +45,12 @@ var waitStatus = function(spec, my) {
}
priv.job_id_a.push(job.getId());
};
/**
* The status stops to wait for this job.
* @method dontWaitForJob
* @param {object} job The job to stop waiting for.
*/
that.dontWaitForJob = function(job) {
var i, tmp_job_id_a = [];
for (i = 0; i < priv.job_id_a.length; i+= 1) {
......@@ -40,9 +61,19 @@ var waitStatus = function(spec, my) {
priv.job_id_a = tmp_job_id_a;
};
/**
* The status must wait for some milliseconds.
* @method waitForTime
* @param {number} ms The number of milliseconds
*/
that.waitForTime = function(ms) {
priv.threshold = Date.now() + ms;
};
/**
* The status stops to wait for some time.
* @method stopWaitForTime
*/
that.stopWaitForTime = function() {
priv.threshold = 0;
};
......@@ -61,5 +92,14 @@ var waitStatus = function(spec, my) {
waitforjob:priv.job_id_a};
};
/**
* Checks if this status is waitStatus
* @method isWaitStatus
* @return {boolean} true
*/
that.isWaitStatus = function () {
return true;
};
return that;
};
......@@ -5,7 +5,6 @@ var storage = function(spec, my) {
// Attributes //
var priv = {};
priv.type = spec.type || '';
// my.jio exists
// Methods //
that.getType = function() {
......@@ -22,6 +21,8 @@ var storage = function(spec, my) {
*/
that.execute = function(command) {
that.validate(command);
that.done = command.done;
that.fail = command.fail;
command.executeOn(that);
};
......@@ -68,5 +69,8 @@ var storage = function(spec, my) {
return '';
};
that.done = function() {};
that.fail = function() {};
return that;
};
var storageHandler = function(spec, my) {
var that = storage(spec, my);
spec = spec || {};
my = my || {};
// Attributes //
var priv = {};
priv.storage_a = spec.storagelist || [];
var that = storage( spec, my );
// Methods //
/**
* It is called before the execution.
* Override this function.
* @method beforeExecute
* @param {object} command The command.
*/
that.beforeExecute = function(command) {};
/**
* Execute the command according to this storage.
* @method execute
* @param {object} command The command.
*/
that.execute = function(command) {
var i;
that.validate(command);
that.beforeExecute(command);
for(i = 0; i < priv.storage_a.length; i++) {
priv.storage_a[i].execute(command);
}
that.afterExecute(command);
};
/**
* Is is called after the execution.
* Override this function.
* @method afterExecute
* @param {object} command The command.
*/
that.afterExecute = function(command) {
command.done();
};
/**
* Returns a serialized version of this storage
* @method serialized
* @return {object} The serialized storage.
*/
that.serialized = function() {
return {type:priv.type,
storagelist:priv.storagelist};
that.addJob = function (storage,command) {
my.jobManager.addJob ( job({storage:storage, command:command}), my );
};
return that;
......
......@@ -31,7 +31,7 @@ objectifyDocumentArray = function (array) {
}
return obj;
},
addFile = function (user,appid,file) {
addFileToLocalStorage = function (user,appid,file) {
var i, l, found = false, filenamearray,
userarray = LocalOrCookieStorage.getItem('jio/local_user_array') || [];
for (i = 0, l = userarray.length; i < l; i+= 1) {
......@@ -58,7 +58,7 @@ addFile = function (user,appid,file) {
'jio/local/'+user+'/'+appid+'/'+file.name,
file);
},
removeFile = function (user,appid,file) {
removeFileFromLocalStorage = function (user,appid,file) {
var i, l, newarray = [],
filenamearray =
LocalOrCookieStorage.getItem(
......@@ -387,421 +387,331 @@ test ('Document save', function () {
o.jio.stop();
});
// test ('Document load', function () {
// // Test if LocalStorage can load documents.
// // We launch a loading from localstorage and we check if the file is
// // realy loaded.
test ('Document load', function () {
// Test if LocalStorage can load documents.
// We launch a loading from localstorage and we check if the file is
// realy loaded.
// 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');
// o.jio.loadDocument(
// {'name':'file','onResponse': o.f,'max_tries':1});
// clock.tick(510);
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
// o.jio = JIO.newJio({'type':'local','user_name':'MrLoadName'},
// {"ID":'jiotests'});
// // load a non existing file
// LocalOrCookieStorage.deleteItem ('jio/local/MrLoadName/jiotests/file');
// mytest ('status','fail');
// // re-load file after saving it manually
// doc = {'name':'file','content':'content',
// 'last_modified':1234,'creation_date':1000};
// LocalOrCookieStorage.setItem (
// 'jio/local_file_name_array/MrLoadName/jiotests',['file']);
// LocalOrCookieStorage.setItem ('jio/local/MrLoadName/jiotests/file',doc);
// mytest ('return_value',doc);
var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this;
o.spy = function(res,value,message) {
o.f = function(result) {
if (res === 'status') {
deepEqual (result.status.getLabel(),value,message);
} else {
deepEqual (result.value,value,message);
}
};
o.t.spy(o,'f');
};
o.tick = function (value, tick) {
o.clock.tick(tick || 1000);
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
}
};
// o.jio.stop();
// });
o.jio = JIO.newJio({type:'local',username:'MrLoadName',
applicationname:'jiotests'});
// save and check document existence
o.doc = {name:'file',content:'content',
last_modified:1234,creation_date:1000};
// test ('Get document list', function () {
// // Test if LocalStorage can get a list of documents.
// // We create 2 documents inside localStorage to check them.
o.spy('status','fail','loading document failure');
o.jio.loadDocument('file',{onResponse:o.f,max_retry:1});
o.tick();
// var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
// doc1 = {}, doc2 = {},
// mytest = function (value){
// o.f = function (result) {
// deepEqual (objectifyDocumentArray(result.return_value),
// objectifyDocumentArray(value),'getting list');
// };
// t.spy(o,'f');
// o.jio.getDocumentList({'onResponse': o.f,'max_tries':1});
// clock.tick(510);
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
// o.jio = JIO.newJio({'type':'local','user_name':'MrListName'},
// {"ID":'jiotests'});
// doc1 = {'name':'file','content':'content',
// 'last_modified':1,'creation_date':0};
// doc2 = {'name':'memo','content':'test',
// 'last_modified':5,'creation_date':2};
// addFile ('MrListName','jiotests',doc1);
// addFile ('MrListName','jiotests',doc2);
// delete doc1.content;
// delete doc2.content;
// mytest ([doc1,doc2]);
LocalOrCookieStorage.setItem (
'jio/local_file_name_array/MrLoadName/jiotests',['file']);
LocalOrCookieStorage.setItem ('jio/local/MrLoadName/jiotests/file',o.doc);
o.spy('value',o.doc,'loading document success');
o.jio.loadDocument('file',{onResponse:o.f,max_retry:1});
o.tick();
// o.jio.stop();
// });
o.jio.stop();
});
// test ('Document remove', function () {
// // Test if LocalStorage can remove documents.
// // We launch a remove from localstorage and we check if the file is
// // realy removed.
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 = {}, clock = this.sandbox.useFakeTimers(), t = this,
// mytest = function (){
// o.f = function (result) {
// deepEqual(result.status,'done','removing document');};
// t.spy(o,'f');
// o.jio.removeDocument(
// {'name':'file','onResponse': o.f,'max_tries':1});
// clock.tick(510);
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// } else {
// // check if the file is still there
// o.tmp = LocalOrCookieStorage.getItem (
// 'jio/local/MrRemoveName/jiotests/file');
// ok (!o.tmp, 'check no content');
// }
// };
// o.jio = JIO.newJio({'type':'local','user_name':'MrRemoveName'},
// {"ID":'jiotests'});
// // test removing a file
// LocalOrCookieStorage.setItem ('jio/local/MrRemoveName/jiotests/file',{});
// mytest ();
var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this;
o.mytest = function (value){
o.f = function (result) {
deepEqual (objectifyDocumentArray(result.value),
objectifyDocumentArray(value),'getting list');
};
o.t.spy(o,'f');
o.jio.getDocumentList('.',{onResponse: o.f,max_retry:1});
o.clock.tick(1000);
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
}
};
o.jio = JIO.newJio({type:'local',username:'MrListName',
applicationname:'jiotests'});
o.doc1 = {name:'file',content:'content',
last_modified:1,creation_date:0};
o.doc2 = {name:'memo',content:'test',
last_modified:5,creation_date:2};
addFileToLocalStorage ('MrListName','jiotests',o.doc1);
addFileToLocalStorage ('MrListName','jiotests',o.doc2);
delete o.doc1.content;
delete o.doc2.content;
o.mytest ([o.doc1,o.doc2]);
// o.jio.stop();
// });
o.jio.stop();
});
// module ('Jio DAVStorage');
test ('Document remove', function () {
// Test if LocalStorage can remove documents.
// We launch a remove from localstorage and we check if the file is
// realy removed.
// test ('Check name availability', function () {
// // Test if DavStorage can check the availabality of a name.
var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this;
o.mytest = function (){
o.f = function (result) {
deepEqual(result.status.getLabel(),'done','removing document');
};
o.t.spy(o,'f');
o.jio.removeDocument('file',{onResponse: o.f,max_retry:1});
o.clock.tick(1000);
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
} else {
// check if the file is still there
o.tmp = LocalOrCookieStorage.getItem (
'jio/local/MrRemoveName/jiotests/file');
ok (!o.tmp, 'check no content');
}
};
o.jio = JIO.newJio({type:'local',username:'MrRemoveName',
applicationname:'jiotests'});
// test removing a file
LocalOrCookieStorage.setItem ('jio/local/MrRemoveName/jiotests/file',{});
o.mytest ();
// var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
// mytest = function (method,value,errno) {
// var server = t.sandbox.useFakeServer();
// server.respondWith ("PROPFIND",
// "https://ca-davstorage:8080/dav/davcheck/",
// [errno, {'Content-Type': 'text/xml' },
// '']);
// o.f = function (result) {
// deepEqual(result[method],value,'checking name availability');};
// t.spy(o,'f');
// o.jio.checkNameAvailability({'user_name':'davcheck','onResponse':o.f,
// 'max_tries':1});
// clock.tick(500);
// server.respond();
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
o.jio.stop();
});
// o.jio = JIO.newJio({'type':'dav','user_name':'davcheck',
// 'password':'checkpwd',
// 'url':'https://ca-davstorage:8080'},
// {'ID':'jiotests'});
// // 404 error, the name does not exist, name is available.
// mytest ('return_value',true,404);
// // 200 error, responding ok, the name already exists, name is not available.
// mytest ('return_value',false,200);
// // 405 error, random error
// mytest ('status','fail',405);
module ('Jio DAVStorage');
// o.jio.stop();
// });
test ('Document load', function () {
// Test if DavStorage can load documents.
// test ('Document load', function () {
// // Test if DavStorage can load documents.
// 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",
// [errprop,{'Content-Type':'text/xml; charset="utf-8"'},
// davload]);
// server.respondWith (
// "GET","https://ca-davstorage:8080/dav/davload/jiotests/file",
// [errget,{},'content']);
// o.f = function (result) {
// deepEqual (result.return_value,doc,message);};
// t.spy(o,'f');
// o.jio.loadDocument({'name':'file','onResponse':o.f,'max_tries':1});
// clock.tick(500);
// server.respond();
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
// o.jio = JIO.newJio({'type':'dav','user_name':'davload',
// 'password':'checkpwd',
// 'url':'https://ca-davstorage:8080'},
// {'ID':'jiotests'});
// // note: http errno:
// // 200 OK
// // 201 Created
// // 204 No Content
// // 207 Multi Status
// // 403 Forbidden
// // 404 Not Found
// // load an inexistant document.
// mytest ('load inexistant document',undefined,404,404);
// // load a document.
// mytest ('load document',{'name':'file','content':'content',
// 'last_modified':1335953199000,
// 'creation_date':1335953202000},207,200);
// o.jio.stop();
// });
var o = {};
o.davload = getXML('responsexml/davload'),
o.clock = this.sandbox.useFakeTimers();
o.t = this;
o.mytest = function (message,doc,errprop,errget) {
var server = o.t.sandbox.useFakeServer();
server.respondWith (
"PROPFIND","https://ca-davstorage:8080/dav/davload/jiotests/file",
[errprop,{'Content-Type':'text/xml; charset="utf-8"'},
o.davload]);
server.respondWith (
"GET","https://ca-davstorage:8080/dav/davload/jiotests/file",
[errget,{},'content']);
o.f = function (result) {
deepEqual (result.value,doc,message);
};
o.t.spy(o,'f');
o.jio.loadDocument('file',{onResponse:o.f,max_retry:1});
o.clock.tick(1000);
server.respond();
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
}
};
o.jio = JIO.newJio({type:'dav',username:'davload',
password:'checkpwd',
url:'https://ca-davstorage:8080',
applicationname:'jiotests'});
// note: http errno:
// 200 OK
// 201 Created
// 204 No Content
// 207 Multi Status
// 403 Forbidden
// 404 Not Found
// load an inexistant document.
o.mytest ('load inexistant document',undefined,404,404);
// load a document.
o.mytest ('load document',{name:'file',content:'content',
last_modified:1335953199000,
creation_date:1335953202000},207,200);
o.jio.stop();
});
// test ('Document save', function () {
// // Test if DavStorage can save documents.
// var davsave = getXML('responsexml/davsave'),
// o = {}, clock = this.sandbox.useFakeTimers(), t = this,
// mytest = function (message,value,errnoput,errnoprop) {
// var server = t.sandbox.useFakeServer();
// server.respondWith (
// // lastmodified = 7000, creationdate = 5000
// "PROPFIND","https://ca-davstorage:8080/dav/davsave/jiotests/file",
// [errnoprop,{'Content-Type':'text/xml; charset="utf-8"'},
// davsave]);
// server.respondWith (
// "PUT",
// "https://ca-davstorage:8080/dav/davsave/jiotests/file",
// [errnoput, {'Content-Type':'x-www-form-urlencoded'},
// 'content']);
// server.respondWith (
// "GET","https://ca-davstorage:8080/dav/davsave/jiotests/file",
// [errnoprop===207?200:errnoprop,{},'content']);
// // server.respondWith ("MKCOL","https://ca-davstorage:8080/dav",
// // [200,{},'']);
// // server.respondWith ("MKCOL","https://ca-davstorage:8080/dav/davsave",
// // [200,{},'']);
// // server.respondWith ("MKCOL",
// // "https://ca-davstorage:8080/dav/davsave/jiotests",
// // [200,{},'']);
// o.f = function (result) {
// deepEqual (result.status,value,message);};
// t.spy(o,'f');
// o.jio.saveDocument({'name':'file','content':'content',
// 'onResponse':o.f,'max_tries':1});
// clock.tick(500);
// server.respond();
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
// o.jio = JIO.newJio({'type':'dav','user_name':'davsave',
// 'password':'checkpwd',
// 'url':'https://ca-davstorage:8080'},
// {'ID':'jiotests'});
// // note: http errno:
// // 200 OK
// // 201 Created
// // 204 No Content
// // 207 Multi Status
// // 403 Forbidden
// // 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);
// // the document does not exist, we want to create it
// mytest('create document','done',201,404);
// clock.tick(8000);
// // the document already exists, we want to overwrite it
// mytest('overwrite document','done',204,207);
// o.jio.stop();
// });
test ('Document save', function () {
// Test if DavStorage can save documents.
// test ('Get Document List', function () {
// // Test if DavStorage can get a list a document.
// 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/',
// [errnoprop,{'Content-Type':'text/xml; charset="utf-8"'},
// davlist]);
// o.f = function (result) {
// if (result.status === 'fail') {
// deepEqual (result.return_value, value, message);
// } else {
// deepEqual (objectifyDocumentArray(result.return_value),
// objectifyDocumentArray(value),message);
// }
// };
// t.spy(o,'f');
// o.jio.getDocumentList({'onResponse':o.f,'max_tries':1});
// clock.tick(500);
// server.respond();
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
// o.jio = JIO.newJio({'type':'dav','user_name':'davlist',
// 'password':'checkpwd',
// 'url':'https://ca-davstorage:8080'},
// {'ID':'jiotests'});
// mytest('fail to get list',undefined,404);
// mytest('getting list',[{'name':'file','creation_date':1335962911000,
// 'last_modified':1335962907000},
// {'name':'memo','creation_date':1335894073000,
// 'last_modified':1335955713000}],207);
// o.jio.stop();
// });
var o = {};
o.davsave = getXML('responsexml/davsave');
o.clock = this.sandbox.useFakeTimers();
o.t = this;
o.mytest = function (message,value,errnoput,errnoprop) {
var server = o.t.sandbox.useFakeServer();
server.respondWith (
// lastmodified = 7000, creationdate = 5000
"PROPFIND","https://ca-davstorage:8080/dav/davsave/jiotests/file",
[errnoprop,{'Content-Type':'text/xml; charset="utf-8"'},
o.davsave]);
server.respondWith (
"PUT",
"https://ca-davstorage:8080/dav/davsave/jiotests/file",
[errnoput, {'Content-Type':'x-www-form-urlencoded'},
'content']);
server.respondWith (
"GET","https://ca-davstorage:8080/dav/davsave/jiotests/file",
[errnoprop===207?200:errnoprop,{},'content']);
// server.respondWith ("MKCOL","https://ca-davstorage:8080/dav",
// [200,{},'']);
// server.respondWith ("MKCOL","https://ca-davstorage:8080/dav/davsave",
// [200,{},'']);
// server.respondWith ("MKCOL",
// "https://ca-davstorage:8080/dav/davsave/jiotests",
// [200,{},'']);
o.f = function (result) {
deepEqual (result.status.getLabel(),value,message);
};
o.t.spy(o,'f');
o.jio.saveDocument('file','content',{onResponse:o.f,max_retry:1});
o.clock.tick(1000);
server.respond();
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
}
};
o.jio = JIO.newJio({type:'dav',username:'davsave',
password:'checkpwd',
url:'https://ca-davstorage:8080',
applicationname:'jiotests'});
// note: http errno:
// 200 OK
// 201 Created
// 204 No Content
// 207 Multi Status
// 403 Forbidden
// 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);
// the document does not exist, we want to create it
o.mytest('create document','done',201,404);
o.clock.tick(8000);
// the document already exists, we want to overwrite it
o.mytest('overwrite document','done',204,207);
o.jio.stop();
});
// test ('Remove document', function () {
// // Test if DavStorage can remove documents.
test ('Get Document List', function () {
// Test if DavStorage can get a list a document.
// 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",
// [errnodel,{},'']);
// o.f = function (result) {
// deepEqual (result.status,value,message);};
// t.spy(o,'f');
// o.jio.removeDocument({'name':'file','onResponse':o.f,'max_tries':1});
// clock.tick(500);
// server.respond();
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
// o.jio = JIO.newJio({'type':'dav','user_name':'davremove',
// 'password':'checkpwd',
// 'url':'https://ca-davstorage:8080'},
// {'ID':'jiotests'});
var o = {};
o.davlist = getXML('responsexml/davlist');
o.clock = this.sandbox.useFakeTimers();
o.t = this;
o.mytest = function (message,value,errnoprop) {
var server = o.t.sandbox.useFakeServer();
server.respondWith (
"PROPFIND",'https://ca-davstorage:8080/dav/davlist/jiotests/',
[errnoprop,{'Content-Type':'text/xml; charset="utf-8"'},
o.davlist]);
o.f = function (result) {
if (result.status.getLabel() === 'fail') {
deepEqual (result.value, value, message);
} else {
deepEqual (objectifyDocumentArray(result.value),
objectifyDocumentArray(value),message);
}
};
o.t.spy(o,'f');
o.jio.getDocumentList('.',{onResponse:o.f,max_retry:1});
o.clock.tick(1000);
server.respond();
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
}
};
o.jio = JIO.newJio({type:'dav',username:'davlist',
password:'checkpwd',
url:'https://ca-davstorage:8080',
applicationname:'jiotests'});
o.mytest('fail to get list',undefined,404);
o.mytest('getting list',[{name:'file',creation_date:1335962911000,
last_modified:1335962907000},
{name:'memo',creation_date:1335894073000,
last_modified:1335955713000}],207);
o.jio.stop();
});
// mytest('remove document','done',204);
// mytest('remove an already removed document','done',404);
// o.jio.stop();
// });
test ('Remove document', function () {
// Test if DavStorage can remove documents.
var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this;
o.mytest = function (message,value,errnodel) {
var server = o.t.sandbox.useFakeServer();
server.respondWith (
"DELETE","https://ca-davstorage:8080/dav/davremove/jiotests/file",
[errnodel,{},'']);
o.f = function (result) {
deepEqual (result.status.getLabel(),value,message);
};
o.t.spy(o,'f');
o.jio.removeDocument('file',{onResponse:o.f,max_retry:1});
o.clock.tick(1000);
server.respond();
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
}
};
o.jio = JIO.newJio({type:'dav',username:'davremove',
password:'checkpwd',
url:'https://ca-davstorage:8080',
appliactionname:'jiotests'});
// module ('Jio ReplicateStorage');
o.mytest('remove document','done',204);
o.mytest('remove an already removed document','done',404);
o.jio.stop();
});
// 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...
module ('Jio ReplicateStorage');
// var o = {}, clock = this.sandbox.useFakeTimers(), t = this,
// mytest = function (message,value) {
// o.f = function (result) {
// deepEqual (result.return_value,value,message);
// };
// t.spy(o,'f');
// o.jio.checkNameAvailability({'user_name':'Dummy','onResponse':o.f,
// 'max_tries':o.max_tries});
// clock.tick(300000);
// if (!o.f.calledOnce) {
// ok(false,'no respose / too much results');
// }
// };
// o.max_tries = 1;
// // DummyStorageAllOK,OK
// o.jio = JIO.newJio({'type':'replicate','storage_array':[
// {'type':'dummyallok','user_name':'1'},
// {'type':'dummyallok','user_name':'2'}]},
// {'ID':'jiotests'});
// mytest('DummyStoragesAllOK,OK : name available',true);
// o.jio.stop();
// // DummyStorageAllOK,Fail
// o.jio = JIO.newJio({'type':'replicate','storage_array':[
// {'type':'dummyallok','user_name':'1'},
// {'type':'dummyallfail','user_name':'2'}]},
// {'ID':'jiotests'});
// mytest('DummyStoragesAllOK,Fail : name not available',undefined);
// o.jio.stop();
// // DummyStorageAllFail,OK
// o.jio = JIO.newJio({'type':'replicate','storage_array':[
// {'type':'dummyallfail','user_name':'1'},
// {'type':'dummyallok','user_name':'2'}]},
// {'ID':'jiotests'});
// mytest('DummyStoragesAllFail,OK : name not available',undefined);
// o.jio.stop();
// // DummyStorageAllFail,Fail
// o.jio = JIO.newJio({'type':'replicate','storage_array':[
// {'type':'dummyallfail','user_name':'1'},
// {'type':'dummyallfail','user_name':'2'}]},
// {'ID':'jiotests'});
// mytest('DummyStoragesAllFail,Fail : fail to check name',undefined);
// o.jio.stop();
// // DummyStorageAllOK,3Tries
// o.max_tries = 3 ;
// o.jio = JIO.newJio({'type':'replicate','storage_array':[
// {'type':'dummyallok','user_name':'1'},
// {'type':'dummyall3tries','user_name':'2'}]},
// {'ID':'jiotests'});
// mytest('DummyStoragesAllOK,3Tries : name available',true);
// o.jio.stop();
// // DummyStorageAll{3tries,{3tries,3tries},3tries}
// o.max_tries = 3 ;
// o.jio = JIO.newJio({'type':'replicate','storage_array':[
// {'type':'dummyall3tries','user_name':'1'},
// {'type':'replicate','storage_array':[
// {'type':'dummyall3tries','user_name':'2'},
// {'type':'dummyall3tries','user_name':'3'}]},
// {'type':'dummyall3tries','user_name':'4'}]},
// {'ID':'jiotests'});
// mytest('DummyStorageAll{3tries,{3tries,3tries},3tries} : name available',
// true);
// o.jio.stop();
// });
test ('Document load', function () {
// Test if ReplicateStorage can load several documents.
// test ('Document load', function () {
// // Test if ReplicateStorage can load several documents.
var o = {}; o.clock = this.sandbox.useFakeTimers(); o.t = this;
o.mytest = function (message,doc) {
o.f = function (result) {
deepEqual (result.value,doc,message);};
o.t.spy(o,'f');
o.jio.loadDocument('file',{onResponse:o.f,max_retry:3});
o.clock.tick(100000);
if (!o.f.calledOnce) {
ok(false, 'no response / too much results');
}
};
o.jio = JIO.newJio({type:'replicate',storagelist:[
{type:'dummyallok',username:'1'},
{type:'dummyallok',username:'2'}]});
console.log (o.jio.getId());
o.mytest('DummyStorageAllOK,OK: load same file',{
name:'file',content:'content',
last_modified:15000,
creation_date:10000});
o.jio.stop();
// var o = {}; var clock = this.sandbox.useFakeTimers(); var t = this;
// var mytest = function (message,doc) {
// o.f = function (result) {
// deepEqual (result.return_value,doc,message);};
// t.spy(o,'f');
// o.jio.loadDocument({'name':'file','onResponse':o.f});
// clock.tick(100000);
// if (!o.f.calledOnce) {
// ok(false, 'no response / too much results');
// }
// };
// o.jio=JIO.newJio({'type':'replicate','user_name':'Dummy','storage_array':[
// {'type':'dummyallok','user_name':'1'},
// {'type':'dummyallok','user_name':'2'}]},
// {'ID':'jiotests'});
// mytest('DummyStorageAllOK,OK: load same file',{
// 'name':'file','content':'content',
// 'last_modified':15000,
// 'creation_date':10000});
// o.jio.stop();
// o.jio=JIO.newJio({'type':'replicate','user_name':'Dummy','storage_array':[
// {'type':'dummyallok','user_name':'1'},
// {'type':'dummyall3tries','user_name':'2'}]},
// {'ID':'jiotests'});
// mytest('DummyStorageAllOK,3tries: load 2 different files',{
// 'name':'file','content':'content',
// 'last_modified':15000,
// 'creation_date':10000});
o.jio = JIO.newJio({type:'replicate',storagelist:[
{type:'dummyall3tries'},
{type:'dummyallok'}]});
console.log (o.jio.getId());
o.mytest('DummyStorageAllOK,3tries: load 2 different files',{
name:'file',content:'content',
last_modified:15000,
creation_date:10000});
// o.jio.stop();
// });
o.jio.stop();
});
// test ('Document save', function () {
// // Test if ReplicateStorage can save several documents.
......
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