/* SCCDXML exporter plugin*/
const {
__errorContinuable,
__httpReq,
__wHttpReq,
__postInternalErrorMsg, __postMessage,
__sequenceNumber,
__successContinuable,
__uri_to_id
} = require("../__worker");
const _do = require("../___do");
const _utils = require('../utils');
const _fs = _do.convert(require('fs'), ['readFile', 'writeFile', 'readdir']);
const _fspp = _do.convert(require('../___fs++'), ['mkdirs']);
module.exports = {
'interfaces' : [{'method':'POST', 'url=':'/exporttosccdxml'}],
'csworker' :
function(resp,method,uri,reqData,wcontext)
{
var self = this,
actions = [__wHttpReq('GET','/current.model?wid='+wcontext.__aswid)];
_do.chain(actions)(
function(asdata){
var writeActions = [_fspp.mkdirs('./exported_to_sccdxml/classes/')];
_do.chain(writeActions) (
function() {
var file_contents = '',
as = _utils.jsonp(asdata['data']),
type_map = {},
type_map_keys = {},
incoming = {},
outgoing = {};
for (var key in as.nodes) {
var node = as.nodes[key];
if (!(node['$type'] in type_map)) {
type_map[node['$type']] = [];
type_map_keys[node['$type']] = [];
}
type_map[node['$type']].push(node);
type_map_keys[node['$type']].push(key);
node['$key'] = key;
}
function xml_safe(str) {
return str.replace(/&/g, "&").replace(/>/g, ">").replace(/\n';
}
else if(r['scope'].lastIndexOf("output(", 0) === 0){
contents += ' scope="output" port="' + r['scope'].slice(7, -1)+ '">\n';
}
else{
contents += ' scope="' + r['scope'] + '">\n';
}
let args = r['arguments'];
for (var aidx in args){
var arg = args[aidx];
if(arg != ""){
contents += '\n';
}
}
contents += '\n';
}
return contents;
}
function resolve_transitions(state){
contents = "";
if(outgoing[state['$key']] == undefined){
return "";
}
var transitions = outgoing[state['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/transition';}).map(function(tid) {return as.nodes[tid];});
for (var tidx in transitions){
var transition = transitions[tidx];
contents += " 0){
contents += 'after="' + xml_safe(transition['after']['value']) + '" ';
}
if(transition['event']['value'].length > 0){
contents += 'event="' + transition['event']['value'] + '" ';
}
if(transition['guard']['value'].length > 0){
contents += 'cond="' + xml_safe(transition['guard']['value']) + '" ';
}
if(transition['port']['value'].length > 0){
contents += 'port="' + transition['port']['value'] + '" ';
}
var target = as.nodes[outgoing[transition['$key']][0]];
contents += 'target="' + find_path(state, target) + '" ';
contents += '>\n';
var parameters = transition['parameters']['value'];
for(var pidx in parameters){
var param = parameters[pidx];
contents += '\n';
}
if(transition['action']['value'].length > 0){
contents += "\n";
}
var raise = transition['raise']['value'];
contents += write_raise(raise);
contents += '\n';
}
return contents;
}
function find_priority(state){
state = as.nodes[state['$key']];
if(state['option']['value'] == "OTF"){
return "source_parent";
}
else if(state['option']['value'] == "ITF"){
return "source_child";
}
else {
console.log("Unknown conflict resolution selected: " + state['option']['value']);
return "undefined";
}
}
function add_actions(state){
contents = "\n";
state = as.nodes[state['$key']];
if(state['entryAction'] == undefined){
return "";
}
contents += "\n";
var raise = state['raiseEntry']['value'];
contents += write_raise(raise);
contents += "\n";
contents += "\n";
contents += "\n";
var raise = state['raiseExit']['value'];
contents += write_raise(raise);
contents += "\n";
return contents;
}
function recursive(state, is_root){
var contents = "";
if(outgoing[state['$key']] == undefined){
var containOC = [],
contain = [],
ocContain = [];
}
else{
var containOC = outgoing[state['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/containOC';}).map(function(tid) {return as.nodes[tid];});
var contain = outgoing[state['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/contain';}).map(function(tid) {return as.nodes[tid];});
var ocContain = outgoing[state['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/ocContain';}).map(function(tid) {return as.nodes[tid];});
var history = outgoing[state['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/includes';}).map(function(tid) {return as.nodes[tid];});
}
var s = as.nodes[state['$key']];
if (is_root){
contents += '\n';
var children = containOC.concat(contain).concat(ocContain).concat(history);
console.log("Children of root: " + children);
for (var cidx in children){
var child = as.nodes[outgoing[children[cidx]['$key']]];
contents += recursive(child, false);
}
contents += resolve_transitions(s);
contents += '\n';
}
else if (containOC.length > 0){
contents += '\n';
var children = containOC.concat(contain).concat(ocContain).concat(history);
for (var cidx in children){
var child = as.nodes[outgoing[children[cidx]['$key']]];
contents += recursive(child, false);
}
contents += resolve_transitions(s);
contents += add_actions(s);
contents += '\n';
}
else if(contain.length + ocContain.length > 0){
contents += '\n';
var children = containOC.concat(contain).concat(ocContain).concat(history);
for (var cidx in children){
var child = as.nodes[outgoing[children[cidx]['$key']]];
contents += recursive(child, false);
}
contents += resolve_transitions(s);
contents += add_actions(s);
contents += '\n';
}
else {
var history = incoming[state['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/includes';}).map(function(tid) {return as.nodes[tid];});
if (history.length > 0){
contents += '\n';
}
else{
contents += '\n';
contents += resolve_transitions(s);
contents += add_actions(s);
contents += '\n';
}
}
return contents;
}
function calc_in_out_rel(rel_type) {
for (var idx in type_map_keys[rel_type]) {
key = type_map_keys[rel_type][idx];
incoming[key] = [];
outgoing[key] = [];
for (var e_key in as.edges) {
var e = as.edges[e_key];
if (e['dest'] == key) {
safe_add(incoming[key], e['src']);
if (!(e['src'] in outgoing)) {
outgoing[e['src']] = [];
}
safe_add(outgoing[e['src']], key);
}
if (e['src'] == key) {
safe_add(outgoing[key], e['dest']);
if (!(e['dest'] in incoming)) {
incoming[e['dest']] = [];
}
safe_add(incoming[e['dest']], key);
}
}
}
}
calc_in_out_rel('/Formalisms/SCCD/SCCD/transition');
calc_in_out_rel('/Formalisms/SCCD/SCCD/Inheritance');
calc_in_out_rel('/Formalisms/SCCD/SCCD/Association');
calc_in_out_rel('/Formalisms/SCCD/SCCD/contain');
calc_in_out_rel('/Formalisms/SCCD/SCCD/containOC');
calc_in_out_rel('/Formalisms/SCCD/SCCD/ocContain');
calc_in_out_rel('/Formalisms/SCCD/SCCD/behaviour');
calc_in_out_rel('/Formalisms/SCCD/SCCD/includes');
for (var key in type_map['/Formalisms/SCCD/SCCD/Class']){
var node = type_map['/Formalisms/SCCD/SCCD/Class'][key],
external = node['external']['value'],
type = node['name']['value'];
if(!external){
file_contents += '\n';
file_contents += '\t\n';
inheritances = outgoing[node['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/Inheritance';}).map(function(tid) {return as.nodes[tid];});
for (var iidx in inheritances){
target = as.nodes[outgoing[inheritances[iidx]['$key']][0]];
file_contents += '\t\t\n';
}
associations = outgoing[node['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/Association';}).map(function(tid) {return as.nodes[tid];});
for (var iidx in associations){
target = as.nodes[outgoing[associations[iidx]['$key']][0]];
file_contents += '\t\t\n';
}
file_contents += '';
file_contents += '\t\n';
for (var fidx in node['methods']['value']){
var func = node['methods']['value'][fidx];
file_contents += '\t\n';
for (var aidx in func['args']){
var arg = func['args'][aidx];
if(arg['name'] == ""){
continue;
}
file_contents += '\t\t\n';
}
file_contents += '\t\n';
file_contents += '\t\n';
}
var behaviour = outgoing[node['$key']].filter(function(el) {return as.nodes[el]['$type'] == '/Formalisms/SCCD/SCCD/behaviour';}).map(function(tid) {return as.nodes[tid];});
var statechart = as.nodes[outgoing[behaviour[0]['$key']][0]];
file_contents += recursive(statechart, true);
file_contents += '\n';
}
}
_fs.writeFileSync('./exported_to_sccdxml/classes/model.xml', file_contents);
__postMessage({'statusCode': 200,
'respIndex': resp});
},
function(writeErr) {__postInternalErrorMsg(resp, writeErr);}
);
},
function(err) {__postInternalErrorMsg(resp, err);}
);
},
'asworker' :
function(resp,method,uri,reqData,wcontext)
{
this.localcontext.counter++;
__postMessage(
{'statusCode':200,
'respIndex':resp});
}
};