exportmtomd.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. {
  2. 'interfaces': [{'method':'POST', 'url=':'/exportmtomd'}],
  3. 'csworker':
  4. function(resp, method, uri, reqData, wcontext) {
  5. var actions = [__wHttpReq('GET', '/current.model?wid=' + wcontext.__aswid)];
  6. _do.chain(actions) (
  7. function(asdata) {
  8. var writeActions = [_fspp.mkdirs('./exported_to_md/')];
  9. _do.chain(writeActions) (
  10. function() {
  11. var file_contents = '';
  12. var as = _utils.jsonp(asdata['data']);
  13. var mms = as['metamodels'];
  14. /*
  15. R: If a pattern metamodel is found: add the original metamodel to the imports list (if not already present)
  16. e.g. rpg.pattern --> rpg
  17. */
  18. var mmsToAdd = [];
  19. for (var i in mms) {
  20. var mm = mms[i];
  21. var pos = mm.search(".pattern");
  22. if (pos != -1) {
  23. var mmToAdd = mm.replace(".pattern", "");
  24. if (mms.indexOf(mmToAdd) == -1) {
  25. mms.push(mmToAdd);
  26. }
  27. }
  28. }
  29. /*
  30. R: Start variable name fixing
  31. */
  32. var reservedWordsPattern = /(Sequence|Model|)/g;
  33. var stringEscapingPattern = /\\/g;
  34. // A word character is a character from a-z, A-Z, 0-9, including the _ (underscore) character.
  35. var nonWordCharPattern = /\W/g;
  36. var reservedWordsPattern = /(Sequence|Model|Edge|Node)/;
  37. var escapes = [[/\//g, "\\\/"], [/\\/g, "\\\\"], [/\"/g, "\\\""]];
  38. var nonWordCharPattern = /\W/g; // A word character is a character from a-z, A-Z, 0-9, including the _ (underscore) character.
  39. function fixName(name) {
  40. name = name.replace(nonWordCharPattern, '_');
  41. var matchArr = name.match(reservedWordsPattern);
  42. if (matchArr != null) {
  43. name = name.replace(matchArr[0], matchArr[0] + '0');
  44. }
  45. return name;
  46. }
  47. function escapeString(str) {
  48. for (i in escapes) {
  49. str = str.replace(escapes[i][0], escapes[i][1]);
  50. }
  51. return str;
  52. }
  53. for (var key in as.nodes) {
  54. // All names of Nodes
  55. var node = as.nodes[key];
  56. // console.log(node.$type);
  57. // console.log(node);
  58. if (node['$type'] != null) { // Fix node name
  59. parts = node['$type'].split('/');
  60. node['$type'] = parts.join('/').replace(parts[parts.length - 1], fixName(parts[parts.length - 1]));
  61. }
  62. for (var prop in node) {
  63. if (prop != '$type') {
  64. // All names and values of properties
  65. if (node[prop]['type'] == 'string' | node[prop]['type'] == 'code')
  66. node[prop]['value'] = escapeString(node[prop]['value']);
  67. }
  68. }
  69. }
  70. /*
  71. R: End variable name fixing
  72. */
  73. extract_md_type = function(mm) {
  74. mm_parts = mm.split('/');
  75. return fixName(mm_parts[mm_parts.length - 1]); // R: Add fixName() here to apply it to types as well
  76. };
  77. // Import extra metamodels
  78. for (var i = mms.length - 1; i >= 0; i--) {
  79. file_contents += 'load "' + extract_md_type(mms[i]) + '"\n';
  80. };
  81. // FIX: Define an auxiliary metamodel which imports all other metamodels and is then instantiated by the main model
  82. var mm = extract_md_type(mms[0]);
  83. var modelName = reqData['name'];
  84. mm = 'Metamodel';
  85. file_contents += '\nModel ' + mm + ' imports ';
  86. for (var i = 0; i < mms.length - 1; i++) {
  87. file_contents += extract_md_type(mms[i]) + ', ';
  88. };
  89. file_contents += extract_md_type(mms[mms.length - 1])
  90. file_contents += ' {} \n\n';
  91. var edges = {};
  92. for (var i = 0; i < as.edges.length; i += 2) {
  93. if (as.edges[i].dest != as.edges[i + 1].src) console.error('The source and destination of the edge are different!');
  94. edges[as.edges[i].dest] = ([as.edges[i].src, as.edges[i + 1].dest]);
  95. };
  96. // Model definition
  97. file_contents += mm + ' ' + modelName + ' {\n'
  98. // console.log('------------');
  99. // console.log(as.nodes);
  100. // console.log('------------');
  101. // console.log(as.edges);
  102. // console.log('------------');
  103. for (var key in as.nodes) {
  104. var node = as.nodes[key];
  105. // console.log('-----start-----');
  106. // console.log(node);
  107. var node_type = extract_md_type(node['$type']);
  108. file_contents += node_type + ' ' + node_type + '_' + key;
  109. file_contents += ' {\n';
  110. if (key in edges) {
  111. file_contents += 'src = ' + extract_md_type(as.nodes[edges[key][0]]['$type']) + '_' + edges[key][0] +';\n';
  112. file_contents += 'dst = ' + extract_md_type(as.nodes[edges[key][1]]['$type']) + '_' + edges[key][1] +';\n';
  113. }
  114. // var incoming = [];
  115. // var outgoing = [];
  116. // for (var e in edges) {
  117. // if (edges[e][0] == key) {
  118. // outgoing.push(e);
  119. // }
  120. // if (edges[e][1] == key) {
  121. // incoming.push(e);
  122. // }
  123. // }
  124. // if (incoming.length) {
  125. // file_contents +=
  126. // incoming.map(function(key) {
  127. // var edge = edges[key];
  128. // var srcKey = edge[0];
  129. // var attr = 'in' + extract_md_type(as.nodes[key]['$type']);
  130. // var type = extract_md_type(as.nodes[srcKey]['$type']);
  131. // var name = type + '_' + srcKey;
  132. // return attr + ' = ' + name + ';';
  133. // }).join('\n') + '\n'
  134. // ;
  135. // }
  136. // if (outgoing.length) {
  137. // file_contents +=
  138. // outgoing.map(function(key) {
  139. // var edge = edges[key];
  140. // var destKey = edge[1];
  141. // var attr = 'out' + extract_md_type(as.nodes[key]['$type']);
  142. // var type = extract_md_type(as.nodes[destKey]['$type']);
  143. // var name = type + '_' + destKey;
  144. // return attr + ' = ' + name + ';';
  145. // }).join('\n') + '\n'
  146. // ;
  147. // }
  148. for (var prop in node) {
  149. if (prop != '$type') {
  150. var pre = '';
  151. var post = '';
  152. if (node[prop]['type'] == 'string' | node[prop]['type'] == 'code') {
  153. pre = '"';
  154. post = '"';
  155. } else if (node[prop]['type'].search('list') >= 0) {
  156. pre = '[';
  157. post = ']';
  158. }
  159. // fixName should be extracted from here and done at the start
  160. file_contents += fixName(prop) + ' = ' + pre + node[prop]['value'] + post + ';\n';
  161. }
  162. }
  163. file_contents += '}\n';
  164. // }
  165. };
  166. file_contents += '}\n'
  167. _fs.writeFileSync('./exported_to_md/' + reqData['name'] + '.mdepth', file_contents);
  168. __postMessage({ 'statusCode': 200,
  169. 'respIndex': resp});
  170. },
  171. function(writeErr) {__postInternalErrorMsg(resp, writeErr);}
  172. );
  173. },
  174. function(err) {__postInternalErrorMsg(resp, err);}
  175. )
  176. },
  177. 'asworker':
  178. function(resp, method, uri, reqData, wcontext)
  179. {
  180. __postMessage(
  181. {'statusCode': 200,
  182. 'respIndex': resp});
  183. }
  184. }