concepto-bridge
Version:
Concepto DSL - Live Mode Bridge
209 lines (199 loc) • 5.72 kB
JavaScript
var mensaje = require('js2xmlparser');
var xml2js = require('xml2js').parseString;
var stripBom = require('strip-bom');
var net = require('net');
var colors = require('colors');
var global = { conn: new net.Socket(),
last_id: '',
last_cmd: '',
filename: '',
fullmap: '',
curr_state: 'wait',
buffer: ''
};
var changes = {}; // node ids struct and its changes.
var defaults = {
'receive_lock' : function(data, callback) {
global.last_id = data['$'].id;
console.log('*** recibimos lock id: ****',global.last_id);
if (callback) callback(data);
},
'welcome' : function(data, callback) {
//console.log('welcome in concepto',data);
if ('$' in data && 'map' in data['$']) {
global.filename = data['$'].filename;
global.fullmap = data['$'].map;
}
if (callback) callback(data);
}
};
exports.getLastID = function() {
return global.last_id;
};
exports.getMap = function(callback) {
if (callback) {
xml2js(global.fullmap, function(err, result) {
try {
var parent_tag = Object.keys(result)[0].toString();
result._filename = global.filename;
callback(result);
} catch(e) {
}
});
} else {
return { filename:global.filename, map:global.fullmap };
}
}
exports.parseXml = function(xml, callback) {
xml2js(xml, function(err, result) {
if (isObject(result)) {
var parent_tag = Object.keys(result)[0].toString();
callback(parent_tag, result[parent_tag]);
} else {
console.log(colors.magenta('smart:parseXml:result is not an object.'));
}
});
};
exports.init = function(callback, options) {
if (options) {
// definimos valores default, en caso de haber options definidos
if ('retry' in options) {
if (options.retry==true) {
defaults['goodbye'] = function() {
console.log('conn:retrying connecting as requested in options.');
exports.init();
}
}
}
//
}
global.conn.connect(9000, 'localhost', function() {
callback();
});
};
exports.on = function(events) {
global.conn.on('error', function(data) {
if ('_error' in events) {
events['_error'](data);
}
});
global.conn.on('data', function(data) {
data = stripBom(data);
var xmlheader = 'encoding="UTF-8"?>';
var msg_continues = false;
if (data.toString().indexOf('<cont>')!=-1) {
// este pack de datos necesita sumarse al buffer
var tt = data.toString().split('<cont>').join('');
global.buffer += tt;
msg_continues = true;
} else {
global.buffer = data.toString();
}
var justcmd = global.buffer;
/*justcmd = justcmd.split('<').join('<')
.split('"').join('"')
.split('<').join('<');*/
//console.log(justcmd.toString().magenta);
var pos = justcmd.toString().indexOf(xmlheader)+xmlheader.length; //
//console.log('pos de utf-8:'.yellow,pos);
if (pos!=-1) {
justcmd = justcmd.slice(pos);
}
if (msg_continues==false) {
try {
var recibido = xml2js(justcmd, function(err, result) {
if (isObject(result)) {
var cmd = Object.keys(result)[0].toString();
var scmd = cmd.split('collaboration_').join('');
if (err) console.log('error en xml2js:',err);
global.last_cmd = scmd;
if (scmd in events) {
//console.log('conn:llamando cmd:'+scmd+' definido en param events');
if (scmd in defaults) { // si habia un default, tambien lo ejecutamos.
defaults[scmd](result[cmd],function(x) {
events[scmd](result[cmd],cmd);
});
} else {
events[scmd](result[cmd]);
}
} else if ('*' in events) {
// evento fallback en si mismo detectado
if (scmd in defaults) {
defaults[scmd](result[cmd],function(x) {
events['*'](result[cmd],cmd);
});
} else {
events['*'](result[cmd],cmd);
}
} else if (scmd in defaults) {
defaults[scmd](result[cmd]);
//console.log('conn:cmd:'+scmd+' no ha sido definido en param events. se omite.');
}
} else {
console.log('smart:result is not object'.red,result);
}
});
} catch(e) {
console.log('error procesando respuesta xml a JS. xml:'.yellow, justcmd);
console.log(e);
}
}
});
};
exports.write = function(cmd, obj) {
var tmp = { cmd: 'collaboration_'+cmd, data:obj };
var msg = mensaje(tmp.cmd, obj);
//msg = msg.split('>').join('>');
msg = msg.split('\n').join('');
//console.log('\nconn:send:enviando:',msg);
global.conn.write(msg+'\r\n','utf-8', function() {
//global.conn.end();
});
};
exports.send = {
login : function(name) {
exports.write('hello', { "@" : { "user_id" : name+"@MacBookdeX.home",
"password" : "depurador123",
}
}
);
},
getlock : function() {
exports.write('require_lock',{});
},
transaction : function(action,undo) {
var espera = 50;
if (global.last_cmd!='receive_lock' || global.last_id=='') {
exports.send.getlock();
espera = 1000;
}
setTimeout(function() {
// ejecutamos con desfase segun si hay o no lock.
exports.write('transaction',{
'@' : {
'id' : global.last_id,
'do_action' : mensaje('compound_action',action),
'undo_action' : mensaje('compound_action',undo)
}
});
}, espera);
}
};
exports.getNodeAfterAction = function(action) {
// returns node struct with attributes and content, after applying transaction.
/*
edit_node_action SOLICITADA SOBRE NODE ID: ID_444377458: { '$': { node: 'ID_444377458' }, text: [ 'animalito1' ] }
retorna:
changes['ID_444377458'] = {
text : 'animalito1',
attributes : {},
icons : ''
}
*/
};
exports.destroy = function() {
global.conn.destroy();
};
var isObject = function(a) {
return (!!a) && (a.constructor === Object);
};