Commit a2d7a860 authored by Tristan Cavelier's avatar Tristan Cavelier

Adding removeDocument to conflict manager storage

parent b4734c55
...@@ -3,11 +3,12 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -3,11 +3,12 @@ var newConflictManagerStorage = function ( spec, my ) {
spec = spec || {}; spec = spec || {};
my = my || {}; my = my || {};
var local_namespace = 'jio/conflictmanager/';
priv.username = spec.username || ''; priv.username = spec.username || '';
var storage_exists = (spec.storage?true:false); var storage_exists = (spec.storage?true:false);
priv.secondstorage_spec = spec.storage || {type:'base'}; priv.secondstorage_spec = spec.storage || {type:'base'};
priv.secondstorage_string = JSON.stringify (priv.secondstorage_spec)
var local_namespace = 'jio/conflictmanager/'+priv.secondstorage_string+'/';
var super_serialized = that.serialized; var super_serialized = that.serialized;
that.serialized = function () { that.serialized = function () {
...@@ -18,8 +19,7 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -18,8 +19,7 @@ var newConflictManagerStorage = function ( spec, my ) {
that.validateState = function () { that.validateState = function () {
if (!priv.username || storage_exists) { if (!priv.username || storage_exists) {
return 'Need at least two parameter: "owner" and "storage" '+ return 'Need at least two parameter: "owner" and "storage".';
'.';
} }
return ''; return '';
}; };
...@@ -40,6 +40,32 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -40,6 +40,32 @@ var newConflictManagerStorage = function ( spec, my ) {
super_fail(error); super_fail(error);
}; };
priv.loadMetadataFromDistant = function (command,path,onDone,onFail) {
var cloned_option = command.cloneOption ();
cloned_option.onResponse = function () {};
cloned_option.onFail = onFail;
cloned_option.onDone = onDone;
var newcommand = that.newCommand(
'loadDocument',{path:path,
option:cloned_option});
that.addJob ( that.newStorage (priv.secondstorage_spec),
newcommand );
};
priv.saveMetadataToDistant = function (command,path,content,onDone,onFail) {
var cloned_option = command.cloneOption ();
cloned_option.onResponse = function () {};
cloned_option.onFail = onFail;
cloned_option.onDone = onDone;
var newcommand = that.newCommand(
'saveDocument',{path:path,
content:JSON.stringify (content),
option:cloned_option});
newcommand.setMaxRetry (0); // inf
that.addJob ( that.newStorage (priv.secondstorage_spec),
newcommand );
};
/** /**
* Save a document and can manage conflicts. * Save a document and can manage conflicts.
* @method saveDocument * @method saveDocument
...@@ -50,9 +76,8 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -50,9 +76,8 @@ var newConflictManagerStorage = function ( spec, my ) {
local_metadata_file_name = local_namespace + metadata_file_name, local_metadata_file_name = local_namespace + metadata_file_name,
local_file_metadata = {}, // local file.metadata local_file_metadata = {}, // local file.metadata
command_file_metadata = {}, // distant file.metadata command_file_metadata = {}, // distant file.metadata
run_index = 0, run_index = 0, previous_revision = 0,
end = false, is_a_new_file = false, end = false, is_a_new_file = false,
previous_revision = 0,
local_file_hash = hex_sha256 (command.getContent()), local_file_hash = hex_sha256 (command.getContent()),
run = function (index) { run = function (index) {
switch (index) { switch (index) {
...@@ -87,37 +112,35 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -87,37 +112,35 @@ var newConflictManagerStorage = function ( spec, my ) {
run_index ++; run (run_index); run_index ++; run (run_index);
break; break;
case 2: // load metadata from distant case 2: // load metadata from distant
(function () { priv.loadMetadataFromDistant (
var cloned_option = command.cloneOption (); command,metadata_file_name,
cloned_option.onResponse = function () {}; function (result) {
cloned_option.onFail = function (error) { command_file_metadata = JSON.parse (result.content);
run_index ++; run (run_index);
},function (error) {
if (error.status === 404) { if (error.status === 404) {
command_file_metadata = local_file_metadata; command_file_metadata = local_file_metadata;
is_a_new_file = true;
run_index ++; run (run_index); run_index ++; run (run_index);
} else { } else {
run_index = (-10); run_index = (-10);
end = true; end = true;
that.fail(command,error); that.fail(command,error);
} }
}; });
cloned_option.onDone = function (result) {
command_file_metadata = JSON.parse (result.content);
run_index ++; run (run_index);
};
var newcommand = that.newCommand(
'loadDocument',{path:metadata_file_name,
option:cloned_option});
that.addJob ( that.newStorage (priv.secondstorage_spec),
newcommand );
}());
break; break;
case 5: // check conflicts case 5: // check conflicts
var updateMetadataCommon = function () { var updateMetadataCommon = function () {
var original_creation_date; var original_creation_date;
if (is_a_new_file || !command_file_metadata.owner[
command_file_metadata.winner.owner]) {
original_creation_date = now.getTime();
} else {
original_creation_date = command_file_metadata.owner[ original_creation_date = command_file_metadata.owner[
command_file_metadata.winner.owner]. command_file_metadata.winner.owner].
creation_date || now.getTime(); creation_date || now.getTime();
}
if (command_file_metadata.owner[priv.username]) { if (command_file_metadata.owner[priv.username]) {
previous_revision = command_file_metadata.owner[ previous_revision = command_file_metadata.owner[
...@@ -190,9 +213,10 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -190,9 +213,10 @@ var newConflictManagerStorage = function ( spec, my ) {
// if known conflict // if known conflict
if (known_conflict_list[i].hash === if (known_conflict_list[i].hash ===
conflict_hash) { conflict_hash) {
command_file_metadata.conflict_list =
priv.removeValuesFromArrayWhere( priv.removeValuesFromArrayWhere(
command_file_metadata.conflict_list, command_file_metadata.conflict_list,
compare_fun); // FIXME : must remove something! compare_fun);
updateCommandMetadataNotOnConflict(); updateCommandMetadataNotOnConflict();
run_index = 98; run_index = 98;
run (6); run (6);
...@@ -212,26 +236,15 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -212,26 +236,15 @@ var newConflictManagerStorage = function ( spec, my ) {
} }
break; break;
case 6: // save metadata case 6: // save metadata
(function () { priv.saveMetadataToDistant (
var cloned_option = command.cloneOption (); command,metadata_file_name,command_file_metadata,
cloned_option.onResponse = function () {}; function () {
cloned_option.onFail = function (error) { run_index ++; run (run_index);
},function (error) {
run_index = (-10); run_index = (-10);
end = true; end = true;
that.fail(command,error); that.fail(command,error);
}; });
cloned_option.onDone = function () {
run_index ++; run (run_index);
};
var newcommand = that.newCommand(
'saveDocument',{path:metadata_file_name,
content:JSON.stringify (
command_file_metadata),
option:cloned_option});
newcommand.setMaxRetry (0); // inf
that.addJob ( that.newStorage (priv.secondstorage_spec),
newcommand );
}());
break; break;
case 7: // save document revision case 7: // save document revision
(function () { (function () {
...@@ -259,7 +272,11 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -259,7 +272,11 @@ var newConflictManagerStorage = function ( spec, my ) {
break; break;
case 8: case 8:
(function () { (function () {
if ( previous_revision !== 0 ) { if ( previous_revision !== 0 && (
!command_file_metadata.owner[priv.username] ||
previous_revision !==
command_file_metadata.owner[
priv.username].revision ) ) {
var cloned_option = command.cloneOption (); var cloned_option = command.cloneOption ();
cloned_option.onResponse = function () {}; cloned_option.onResponse = function () {};
cloned_option.onFail = function (error) { cloned_option.onFail = function (error) {
...@@ -311,15 +328,9 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -311,15 +328,9 @@ var newConflictManagerStorage = function ( spec, my ) {
run = function (index) { run = function (index) {
switch (index) { switch (index) {
case 0: // load metadata file from distant case 0: // load metadata file from distant
(function () { priv.loadMetadataFromDistant (
var cloned_option = command.cloneOption (); command,metadata_file_name,
cloned_option.onResponse = function () {}; function (result) {
cloned_option.onFail = function (error) {
run_index = (-10);
end = true;
that.fail(command,error);
};
cloned_option.onDone = function (result) {
command_file_metadata = JSON.parse (result.content); command_file_metadata = JSON.parse (result.content);
owner = command.getOption('owner'); owner = command.getOption('owner');
run_index = 98; run_index = 98;
...@@ -331,14 +342,11 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -331,14 +342,11 @@ var newConflictManagerStorage = function ( spec, my ) {
run (2); run (2);
} }
run (1); run (1);
}; },function (error) {
var newcommand = that.newCommand( run_index = (-10);
'loadDocument', end = true;
{path:metadata_file_name, that.fail(command,error);
option:cloned_option}); });
that.addJob ( that.newStorage (priv.secondstorage_spec),
newcommand );
}());
break; break;
case 1: // update local metadata case 1: // update local metadata
LocalOrCookieStorage.setItem (local_metadata_file_name, LocalOrCookieStorage.setItem (local_metadata_file_name,
...@@ -429,14 +437,16 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -429,14 +437,16 @@ var newConflictManagerStorage = function ( spec, my ) {
}; };
cloned_option.onDone = function (result) { cloned_option.onDone = function (result) {
var i; var i;
// log (blue + 'result ' + JSON.stringify (result) + endblue);
// log (green + 'distantstorage ' + JSON.stringify (distantstorage) + endgreen);
for (i = 0; i < result.length; i+= 1) { for (i = 0; i < result.length; i+= 1) {
var splitname = result[i].name.split('.') || []; var splitname = result[i].name.split('.') || [];
var content_object; var content_object;
var doc = {}; var doc = {};
if (splitname[splitname.length-1] === 'metadata') { if (splitname[splitname.length-1] === 'metadata') {
try {
content_object = JSON.parse (result[i].content); content_object = JSON.parse (result[i].content);
} catch (e) {
continue;
}
result_list.push(content_object); result_list.push(content_object);
splitname.length --; splitname.length --;
doc.name = splitname.join('.'); doc.name = splitname.join('.');
...@@ -454,6 +464,9 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -454,6 +464,9 @@ var newConflictManagerStorage = function ( spec, my ) {
return that.done([]); return that.done([]);
}; };
for (i = 0; i < command_file_metadata_list.length; i+= 1) { for (i = 0; i < command_file_metadata_list.length; i+= 1) {
LocalOrCookieStorage.setItem (
command_file_metadata_list[i].name + '.metadata',
result_list[i]);
loadFile(command_file_metadata_list[i], loadFile(command_file_metadata_list[i],
result_list[i].winner.revision, result_list[i].winner.revision,
result_list[i].winner.owner); result_list[i].winner.owner);
...@@ -501,7 +514,193 @@ var newConflictManagerStorage = function ( spec, my ) { ...@@ -501,7 +514,193 @@ var newConflictManagerStorage = function ( spec, my ) {
* @method removeDocument * @method removeDocument
*/ */
that.removeDocument = function (command) { that.removeDocument = function (command) {
that.fail(command,{message:'NIY'}); var metadata_file_name = command.getPath() + '.metadata',
local_metadata_file_name = local_namespace + metadata_file_name,
command_file_metadata = {}, // distant file.metadata
run_index = 0, previous_revision = 0,
end = false, is_a_new_file = false,
run = function (index) {
switch (index) {
case 0:
run_index = 3;
run (2);
run (1);
break;
case 1: // update local metadata
var new_owner_object = {revision:0,hash:'',
last_modified:0,
creation_date:0};
local_file_metadata =
LocalOrCookieStorage.getItem (local_metadata_file_name);
if ( local_file_metadata ) {
// if metadata already exists
if ( !local_file_metadata.owner[priv.username] ) {
local_file_metadata.owner[priv.username] =
new_owner_object;
}
} else {
local_file_metadata = {
winner: {},
owner: {},
conflict_list: []
};
local_file_metadata.winner = {
revision:0,owner:priv.username,hash:''};
local_file_metadata.owner[priv.username] =
new_owner_object;
}
run_index ++; run (run_index);
break;
case 2: // load metadata from distant
priv.loadMetadataFromDistant (
command,metadata_file_name,
function (result) {
command_file_metadata = JSON.parse (result.content);
run_index++; run (run_index);
},function (error) {
if (error.status === 404) {
command_file_metadata = local_file_metadata;
is_a_new_file = true;
run_index++; run (run_index);
return;
}
run_index = (-10);
end = true;
that.fail(command,error);
});
break;
case 5:
var updateMetadataCommon = function () {
if (command_file_metadata.owner[priv.username]) {
previous_revision = command_file_metadata.owner[
priv.username].revision;
delete command_file_metadata.owner[priv.username];
}
};
var updateCommandMetadataNotOnConflict = function () {
updateMetadataCommon();
command_file_metadata.winner.owner = priv.username;
command_file_metadata.winner.revision = 0;
command_file_metadata.winner.hash = '';
};
var updateCommandMetadataOnConflict = function () {
updateMetadataCommon ();
};
// if this is a new file
if (is_a_new_file) {
LocalOrCookieStorage.deleteItem (local_metadata_file_name);
return that.done();
}
// if no conflict
if (local_file_metadata.winner.revision ===
command_file_metadata.winner.revision &&
local_file_metadata.winner.hash ===
command_file_metadata.winner.hash) {
// OK! Now, update distant metadata, store them and remove
updateCommandMetadataNotOnConflict();
LocalOrCookieStorage.setItem (local_metadata_file_name,
command_file_metadata);
run_index = 98;
run (6); // save metadata
run (7); // remove document revision
} else {
// if conflict
var conflict_object = {
label: 'revision',
path: command.getPath(),
conflict_owner: {
name: command_file_metadata.winner.owner,
revision: command_file_metadata.winner.revision,
hash: command_file_metadata.winner.hash}
},
// gen hash
conflict_hash = hex_sha256 (JSON.stringify (
conflict_object));
conflict_object.hash = conflict_hash;
// browse known conflict list
var i, known_conflict_list =
command.getOption('known_conflict_list') || [];
var compare_fun = function (v) {
return (v.hash === conflict_hash);
};
for (i = 0; i < known_conflict_list.length; i+= 1) {
// if known conflict
if (known_conflict_list[i].hash ===
conflict_hash) {
command_file_metadata.conflict_list =
priv.removeValuesFromArrayWhere(
command_file_metadata.conflict_list,
compare_fun);
updateCommandMetadataNotOnConflict();
run_index = 98;
run (6);
run (7);
return;
}
}
updateCommandMetadataOnConflict();
// if unknown conflict
command_file_metadata.conflict_list.push (conflict_object);
run_index = (-10);
end = true;
run (6); // save metadata
run (7); // remove document revision
that.fail(command); // TODO
command.getOption('onConflict')(conflict_object);
}
break;
case 6:
priv.saveMetadataToDistant (
command,metadata_file_name,command_file_metadata,
function () {
run_index ++; run (run_index);
},function (error) {
run_index = (-10);
end = true;
that.fail(command,error);
});
break;
case 7:
(function () {
if ( previous_revision !== 0 && (
!command_file_metadata.owner[priv.username] ||
previous_revision !==
command_file_metadata.owner[
priv.username].revision ) ) {
var cloned_option = command.cloneOption ();
cloned_option.onResponse = function () {};
cloned_option.onFail = function (error) {
run_index = (-10);
end = true;
that.fail(command,error);
};
cloned_option.onDone = function () {
run_index ++; run (run_index);
};
var newcommand = that.newCommand(
'removeDocument',
{path:command.getPath() + '.' +
previous_revision + '.' + priv.username,
option:cloned_option});
newcommand.setMaxRetry (0); // inf
that.addJob ( that.newStorage (priv.secondstorage_spec),
newcommand );
} else {
run_index ++; run (run_index);
}
}());
break;
case 100:
if (!end) {
end = true;
that.done();
return;
}
break;
default: break;
}
};
run (0);
}; };
return that; return that;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment