123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247 |
- {
- 'interfaces': [{'method':'POST', 'url=':'/exportmmtomd'}],
- 'csworker':
- function(resp, method, uri, reqData, wcontext) {
- var actions = [__wHttpReq('GET', '/current.model?wid=' + wcontext.__aswid)];
- _do.chain(actions) (
- function(asdata) {
- var writeActions = [_fspp.mkdirs('./exported_to_md/')];
- _do.chain(writeActions) (
- function() {
- var file_contents = '';
- var as = _utils.jsonp(asdata['data']);
- var edges = {};
- var superclasses = {};
- var superclasses_ids = {};
-
- // R: Replace $* by Node ($* is the wildcard class of AToMPM: metaDepth's Node)
- // R: This is still not 100% safe since Node is no longer in the reservedWordsPattern,
- // so a class could be called Node in atompm and give a compilation error in metadepth
- for (var key in as.nodes) {
- var node = as.nodes[key];
- if (node.name != null && node.name.value == '$*') {
- node.name.value = 'Node';
- }
- }
-
- /*
- R: Start variable name fixing
- */
- var reservedWordsPattern = /(Sequence|Model|Edge|Link)/;
- var escapes = [[/\//g, "\\\/"], [/\\/g, "\\\\"]];
- var nonWordCharPattern = /\W/g; // A word character is a character from a-z, A-Z, 0-9, including the _ (underscore) character.
- function fixName(name) {
- name = name.replace(nonWordCharPattern, '_');
- var matchArr = name.match(reservedWordsPattern);
- if (matchArr != null) {
- name = name.replace(matchArr[0], matchArr[0] + '0');
- }
- return name;
- }
- function escapeString(str) {
- for (i in escapes) {
- str = str.replace(escapes[i][0], escapes[i][1]);
- }
- return str;
- }
-
- for (var key in as.nodes) {
- // All names of Nodes
- // console.log(as);
- var node = as.nodes[key];
- if (node.name != null) {
- node.name.value = fixName(node.name.value);
- // console.log(node.name);
- // console.log(node.attributes);
- if (node.attributes != null) {
- for (var prop in node.attributes['value']) {
- // All names of attributes and (default) values
- node.attributes['value'][prop].name = fixName(node.attributes['value'][prop].name);
- if (node.attributes['value'][prop].type == 'string' | node.attributes['value'][prop].type == 'code')
- node.attributes['value'][prop]['default'] = escapeString(node.attributes['value'][prop]['default']);
- }
- }
- }
- }
- /*
- R: End variable name fixing
- */
-
- extract_md_type = function(mm) {
- mm_parts = mm.split('/');
- return fixName(mm_parts[mm_parts.length - 1]); // R: Add fixName() here to apply it to types as well
- };
-
- for (var i = 0; i < as.edges.length; i += 2) {
- if (as.edges[i].dest != as.edges[i + 1].src) console.error('The source and destination of the edge are different!');
- if (extract_md_type(as.nodes[as.edges[i].dest]['$type']) == 'Inheritance') {
- if (!(as.edges[i].src in superclasses)) {
- superclasses[as.edges[i].src] = [];
- superclasses_ids[as.edges[i].src] = [];
- }
- superclasses[as.edges[i].src].push(as.nodes[as.edges[i + 1].dest]['name']['value']);
- superclasses_ids[as.edges[i].src].push(as.edges[i + 1].dest);
- } else {
- edges[as.edges[i].dest] = ([as.edges[i].src, as.edges[i + 1].dest]);
- }
- };
- // Add superclass Link to all Edges (this is class is not present in AToMPM thus not contained in as.nodes)
- for (var key in as.nodes) {
- // console.log(key);
- var node = as.nodes[key];
- if (key in edges) {
- superclasses[key] = ['Link'];
- }
- }
-
- file_contents += 'Model ' + reqData['name'] + ' {\n'
-
- var sorted_nodes = [];
- var sorted_edges = [];
- var nodes_no_superclasses = [];
- var c_to_superclass = {}
- // copy superclasses dictionary
- for (var key in superclasses_ids) {
- c_to_superclass[key] = superclasses_ids[key].slice(0);
- }
- // create reverse of superclasses: mapping of class to its subclasses
- var c_to_subclasses = {};
- for (var key in superclasses_ids) {
- // console.error(superclasses_ids[key]);
- for (var i in superclasses_ids[key]) {
- var sc = superclasses_ids[key][i];
- if (!(sc in c_to_subclasses)) {
- c_to_subclasses[sc] = [];
- }
- c_to_subclasses[sc].push(key);
- }
- }
- // get all nodes without any superclasses
- for (var key in as.nodes) {
- if (!(key in superclasses_ids)) {
- nodes_no_superclasses.push(key)
- }
- }
- // topological sort
- while (nodes_no_superclasses.length > 0) {
- var n = nodes_no_superclasses.pop();
- if (n in edges) {
- sorted_edges.push(n);
- } else {
- sorted_nodes.push(n);
- }
- for (var i in c_to_subclasses[n]) {
- sc = c_to_subclasses[n][i];
- // console.error(c_to_superclass[sc]);
- c_to_superclass[sc].splice(c_to_superclass[sc].indexOf(n), 1);
- // console.error(c_to_superclass[sc]);
- if (c_to_superclass[sc].length == 0) {
- nodes_no_superclasses.push(sc);
- }
- }
- }
-
- sorted_nodes = sorted_nodes.concat(sorted_edges);
- // console.log('as.nodes:');
- // console.log(as.nodes);
- // console.log('as.edges:');
- // console.log(as.edges);
- // console.log('edges:');
- // console.log(edges);
-
- // If there is at least an edge in the model, add the Link superclass since all edges will extend it
- // console.log(edges);
- if (edges !== {}) { // BUG: This check is currently not working.
- file_contents +=
- 'Node Link {\n' +
- 'src : Node;\n' +
- 'dst : Node;\n' +
- '}\n';
- }
- while (sorted_nodes.length > 0) {
- key = sorted_nodes.shift();
- var node = as.nodes[key];
-
- if (!(node["$type"].search('GlobalConstraint') >= 0 || node["$type"].search('GlobalAction') >= 0 || node["$type"].search('Inheritance') >= 0|| node.name.value == "Node")) {
- // if (key in edges) {
- /*
- var incoming, outgoing;
- for (var e in edges) {
- if (edges[e][0] == key) {
- outgoing = edges[e][1];
- } else if (edges[e][1] == key) {
- incoming = edges[e][0];
- }
- }
- */
- // var incoming = [];
- // var outgoing = [];
- // for (var e in edges) {
- // if (edges[e][0] == key) {
- // outgoing.push(e);
- // }
- // if (edges[e][1] == key) {
- // incoming.push(e);
- // }
- // }
- // No abstract classes in pattern metamodel (RAMification)
- file_contents += 'Node '
- + node.name.value
- + (key in superclasses ? ': ' + superclasses[key].join(', ') : ' ')
- + '{\n';
- // if (incoming.length) {
- // file_contents +=
- // incoming.map(function(i) {return 'in' + as.nodes[i].name.value +
- // ': ' + as.nodes[edges[i][0]]['name']['value'] + '[*];'}).join('\n')
- // + '\n';
- // }
- // if (outgoing.length) {
- // file_contents +=
- // outgoing.map(function(i) {return 'out' + as.nodes[i].name.value +
- // ': ' + as.nodes[edges[i][1]]['name']['value'] + '[*];'}).join('\n')
- // + '\n';
- // }
- var typemapping = {
- 'bool': 'boolean',
- 'string': 'String',
- 'list<string>': 'String[*]',
- 'list<bool>': 'boolean[*]',
- 'list<int>': 'int[*]',
- 'list<float>': 'double[*]',
- 'list<double>': 'double[*]',
- 'list<real>': 'double[*]',
- 'code': 'String'
- }
-
- // DEPRECATED: No longer needed after adding the Link Node
- // if (key in edges) {
- // file_contents += 'in : ' + as.nodes[edges[key][0]]['name']['value'] +';\n';
- // file_contents += 'out : ' + as.nodes[edges[key][1]]['name']['value'] +';\n';
- // }
-
- for (var prop in node.attributes['value']) {
- t = node.attributes['value'][prop].type;
- file_contents += node.attributes['value'][prop].name + ':' + (t in typemapping ? typemapping[t] : t) + (node.attributes['value'][prop]['default'] != '' ? ' = ' + (t.search('list') >= 0 ? '[' : '') + node.attributes['value'][prop]['default'] + (t.search('list') >= 0 ? ']' : '') : '') + ';\n';
- }
- file_contents += '}\n';
- };
- };
- file_contents += '}\n';
- _fs.writeFileSync('./exported_to_md/' + reqData['name'] + '.mdepth', file_contents);
- __postMessage({ 'statusCode': 200,
- 'respIndex': resp});
- },
- function(writeErr) {__postInternalErrorMsg(resp, writeErr);}
- );
- },
- function(err) {__postInternalErrorMsg(resp, err);}
- )
- },
- 'asworker':
- function(resp, method, uri, reqData, wcontext)
- {
- __postMessage(
- {'statusCode': 200,
- 'respIndex': resp});
- }
- }
|