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 ) {
spec = spec || {};
my = my || {};
var local_namespace = 'jio/conflictmanager/';
priv.username = spec.username || '';
var storage_exists = (spec.storage?true:false);
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;
that.serialized = function () {
......@@ -18,8 +19,7 @@ var newConflictManagerStorage = function ( spec, my ) {
that.validateState = function () {
if (!priv.username || storage_exists) {
return 'Need at least two parameter: "owner" and "storage" '+
'.';
return 'Need at least two parameter: "owner" and "storage".';
}
return '';
};
......@@ -40,6 +40,32 @@ var newConflictManagerStorage = function ( spec, my ) {
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.
* @method saveDocument
......@@ -50,9 +76,8 @@ var newConflictManagerStorage = function ( spec, my ) {
local_metadata_file_name = local_namespace + metadata_file_name,
local_file_metadata = {}, // local file.metadata
command_file_metadata = {}, // distant file.metadata
run_index = 0,
run_index = 0, previous_revision = 0,
end = false, is_a_new_file = false,
previous_revision = 0,
local_file_hash = hex_sha256 (command.getContent()),
run = function (index) {
switch (index) {
......@@ -87,37 +112,35 @@ var newConflictManagerStorage = function ( spec, my ) {
run_index ++; run (run_index);
break;
case 2: // load metadata from distant
(function () {
var cloned_option = command.cloneOption ();
cloned_option.onResponse = function () {};
cloned_option.onFail = function (error) {
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);
} else {
run_index = (-10);
end = true;
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;
case 5: // check conflicts
var updateMetadataCommon = function () {
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[
command_file_metadata.winner.owner].
creation_date || now.getTime();
}
if (command_file_metadata.owner[priv.username]) {
previous_revision = command_file_metadata.owner[
......@@ -190,9 +213,10 @@ var newConflictManagerStorage = function ( spec, my ) {
// 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); // FIXME : must remove something!
compare_fun);
updateCommandMetadataNotOnConflict();
run_index = 98;
run (6);
......@@ -212,26 +236,15 @@ var newConflictManagerStorage = function ( spec, my ) {
}
break;
case 6: // save metadata
(function () {
var cloned_option = command.cloneOption ();
cloned_option.onResponse = function () {};
cloned_option.onFail = function (error) {
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);
};
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;
case 7: // save document revision
(function () {
......@@ -259,7 +272,11 @@ var newConflictManagerStorage = function ( spec, my ) {
break;
case 8:
(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 ();
cloned_option.onResponse = function () {};
cloned_option.onFail = function (error) {
......@@ -311,15 +328,9 @@ var newConflictManagerStorage = function ( spec, my ) {
run = function (index) {
switch (index) {
case 0: // load metadata file from distant
(function () {
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 (result) {
priv.loadMetadataFromDistant (
command,metadata_file_name,
function (result) {
command_file_metadata = JSON.parse (result.content);
owner = command.getOption('owner');
run_index = 98;
......@@ -331,14 +342,11 @@ var newConflictManagerStorage = function ( spec, my ) {
run (2);
}
run (1);
};
var newcommand = that.newCommand(
'loadDocument',
{path:metadata_file_name,
option:cloned_option});
that.addJob ( that.newStorage (priv.secondstorage_spec),
newcommand );
}());
},function (error) {
run_index = (-10);
end = true;
that.fail(command,error);
});
break;
case 1: // update local metadata
LocalOrCookieStorage.setItem (local_metadata_file_name,
......@@ -429,14 +437,16 @@ var newConflictManagerStorage = function ( spec, my ) {
};
cloned_option.onDone = function (result) {
var i;
// log (blue + 'result ' + JSON.stringify (result) + endblue);
// log (green + 'distantstorage ' + JSON.stringify (distantstorage) + endgreen);
for (i = 0; i < result.length; i+= 1) {
var splitname = result[i].name.split('.') || [];
var content_object;
var doc = {};
if (splitname[splitname.length-1] === 'metadata') {
try {
content_object = JSON.parse (result[i].content);
} catch (e) {
continue;
}
result_list.push(content_object);
splitname.length --;
doc.name = splitname.join('.');
......@@ -454,6 +464,9 @@ var newConflictManagerStorage = function ( spec, my ) {
return that.done([]);
};
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],
result_list[i].winner.revision,
result_list[i].winner.owner);
......@@ -501,7 +514,193 @@ var newConflictManagerStorage = function ( spec, my ) {
* @method removeDocument
*/
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;
......
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