modelverse_connector.js 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. class ModelVerseConnector {
  2. constructor(address) {
  3. ModelVerseConnector.taskname = "task_manager";
  4. ModelVerseConnector.address = (address == undefined) ? "http://127.0.0.1:8001" : address;
  5. ModelVerseConnector.ERROR = 0;
  6. ModelVerseConnector.WORKING = 1;
  7. ModelVerseConnector.OKAY = 2;
  8. ModelVerseConnector.connected = true;
  9. ModelVerseConnector.curr_model = null;
  10. ModelVerseConnector.element_map = {};
  11. ModelVerseConnector.PM2MV_metamodel_map = {
  12. "/Formalisms/__LanguageSyntax__/SimpleClassDiagram/SimpleClassDiagram" : "formalisms/SimpleClassDiagrams"
  13. };
  14. ModelVerseConnector.MV2PM_metamodel_map = ModelVerseConnector.reverse_dict(ModelVerseConnector.PM2MV_metamodel_map);
  15. }
  16. static reverse_dict(dict){
  17. let ret = {};
  18. for(let key of Object.keys(dict)){
  19. ret[dict[key]] = key;
  20. }
  21. return ret;
  22. }
  23. static set_status(status) {
  24. let red = "rgb(220,20,60)";
  25. let yellow = "rgb(218,165,32)";
  26. let green = "rgb(50,205,50)";
  27. let colours = [red, yellow, green];
  28. let set_colour = function (colour) {
  29. let mv_toolbar = $('#div_toolbar_\\2f Toolbars\\2f ModelVerse\\2f ModelVerse\\2e buttons\\2e model');
  30. mv_toolbar.css("background-color", colour)
  31. };
  32. set_colour(colours[status]);
  33. }
  34. static save_model(model_name, data){
  35. ModelVerseConnector.set_status(ModelVerseConnector.WORKING);
  36. console.log("Save model: " + model_name);
  37. let parsed_data = JSON.parse(data);
  38. // console.log(parsed_data);
  39. let m = JSON.parse(parsed_data['data']['m']);
  40. let mms = JSON.parse(parsed_data['data']['mms']);
  41. //detect the metamodels
  42. if (Object.keys(mms).length > 1){
  43. console.log("Warning: More than one meta-model detected!")
  44. }
  45. let primary_mm_PM = Object.keys(mms)[0];
  46. let primary_mm_MV = ModelVerseConnector.PM2MV_metamodel_map[primary_mm_PM];
  47. //TODO: Allow user to select meta-model when it is not found
  48. // console.log("MV PM: " + primary_mm_PM);
  49. // console.log("MV MM: " + primary_mm_MV);
  50. if (primary_mm_MV == undefined){
  51. WindowManagement.openDialog(_ERROR,'Meta-model may not exist in ModelVerse: "' + primary_mm_PM + '"');
  52. //return;
  53. if (primary_mm_PM.startsWith("/")){
  54. primary_mm_PM = primary_mm_PM.slice(1);
  55. }
  56. primary_mm_MV = primary_mm_PM;
  57. }
  58. let model_delete = {
  59. "data": utils.jsons(["model_delete", model_name])
  60. };
  61. let model_create = {
  62. "data": utils.jsons(["model_add", primary_mm_MV, model_name, ""])
  63. };
  64. let model_edit = {
  65. "data": utils.jsons(["model_modify", model_name, primary_mm_MV])
  66. };
  67. ModelVerseConnector.curr_model = model_name;
  68. ModelVerseConnector.send_command(model_create)
  69. .then(ModelVerseConnector.get_output)
  70. .then(function (data) {
  71. if (data.includes("Model not found")){
  72. ModelVerseConnector.set_status(ModelVerseConnector.ERROR);
  73. WindowManagement.openDialog(_ERROR,data);
  74. return;
  75. }
  76. })
  77. .then(ModelVerseConnector.send_command(model_edit))
  78. .then(ModelVerseConnector.get_output)
  79. .then(function(data){
  80. let node_creation_promises = [];
  81. for (const [key, node] of Object.entries(m.nodes)) {
  82. if (node.name == undefined){
  83. continue;
  84. }
  85. if (!(node.linktype == undefined)){
  86. continue;
  87. }
  88. let node_name = node.name.value;
  89. let node_type = node.$type.split("/").slice(-1)[0];
  90. node_creation_promises.push(ModelVerseConnector.send_command(
  91. {"data": utils.jsons(["instantiate_node", node_type, node_name])}
  92. ));
  93. let set_id = function (id){
  94. ModelVerseConnector.element_map[key] = id.split(" ")[1].replace("\"", "");
  95. };
  96. node_creation_promises.push(ModelVerseConnector.get_output(set_id));
  97. }
  98. let simple_type = ["String", "Int", "Float", "Boolean", "Code", "File", "Map", "List", "ENUM"];
  99. for (let st of simple_type){
  100. node_creation_promises.push(ModelVerseConnector.send_command(
  101. {"data": utils.jsons(["instantiate_node", "SimpleAttribute", st])}
  102. ));
  103. node_creation_promises.push(ModelVerseConnector.get_output());
  104. }
  105. //get cardinalities
  106. let card_dict = {};
  107. let attrib_creation_promises = [];
  108. // console.log("Cardinalities");
  109. for (const [key, node] of Object.entries(m.nodes)) {
  110. if (node.cardinalities == undefined || node.cardinalities.value.length == 0){
  111. continue;
  112. }
  113. //console.log(node);
  114. for (const card of node.cardinalities.value){
  115. //console.log(card);
  116. let cardname = card["type"] + card["dir"];
  117. card_dict[cardname] = [card["min"], card["max"]];
  118. // console.log(card_dict);
  119. }
  120. }
  121. Promise.all(node_creation_promises).then( function(){
  122. let edge_creation_promises = [];
  123. for (const [key, node] of Object.entries(m.nodes)) {
  124. if (node.name == undefined || node.linktype != undefined) {
  125. let node_type = node.$type.split("/").slice(-1)[0];
  126. let node_name = null;
  127. if (node.name != undefined) {
  128. node_name = node.name.value;
  129. }else{
  130. node_name = node_type + key;
  131. }
  132. let src = null;
  133. let dest = null;
  134. for (const [edge_key, edge] of Object.entries(m.edges)) {
  135. if (edge['src'] == key) {
  136. let ed = edge['dest'];
  137. dest = ModelVerseConnector.element_map[ed];
  138. } else if (edge['dest'] == key) {
  139. let es = edge['src'];
  140. src = ModelVerseConnector.element_map[es];
  141. }
  142. }
  143. let set_id = function (id){
  144. ModelVerseConnector.element_map[key] = id.split(" ")[1].replace("\"", "");
  145. };
  146. edge_creation_promises.push(ModelVerseConnector.send_command(
  147. {"data": utils.jsons(["instantiate_edge", node_type, node_name, src, dest])}
  148. ));
  149. edge_creation_promises.push(ModelVerseConnector.get_output(set_id));
  150. }
  151. }
  152. Promise.all(edge_creation_promises).then(function() {
  153. for (const [key, node] of Object.entries(m.nodes)) {
  154. let ele = ModelVerseConnector.element_map[key];
  155. let node_type = node.$type.split("/").slice(-1)[0];
  156. if (node.abstract != undefined && node.abstract.value){
  157. attrib_creation_promises.push(ModelVerseConnector.send_command(
  158. {"data": utils.jsons(["attr_add", ele, "abstract", true])}
  159. ));
  160. attrib_creation_promises.push(ModelVerseConnector.get_output());
  161. }
  162. if (node.name != undefined && node_type != "GlobalConstraint"){
  163. attrib_creation_promises.push(ModelVerseConnector.send_command(
  164. {"data": utils.jsons(["attr_add", ele, "name", node.name.value])}
  165. ));
  166. attrib_creation_promises.push(ModelVerseConnector.get_output());
  167. }
  168. if (node.name != undefined){
  169. // console.log(Object.keys(card_dict));
  170. let src_card = card_dict[node.name.value + "out"];
  171. let trgt_card = card_dict[node.name.value + "in"];
  172. // console.log("Src:");
  173. // console.log(src_card);
  174. if (src_card != undefined){
  175. attrib_creation_promises.push(ModelVerseConnector.send_command(
  176. {"data": utils.jsons(["attr_add", ele, "source_lower_cardinality", src_card[0]])}
  177. ));
  178. attrib_creation_promises.push(ModelVerseConnector.get_output());
  179. attrib_creation_promises.push(ModelVerseConnector.send_command(
  180. {"data": utils.jsons(["attr_add", ele, "source_upper_cardinality", src_card[1]])}
  181. ));
  182. attrib_creation_promises.push(ModelVerseConnector.get_output());
  183. }
  184. // console.log("Trgt:");
  185. // console.log(trgt_card);
  186. if (trgt_card != undefined){
  187. attrib_creation_promises.push(ModelVerseConnector.send_command(
  188. {"data": utils.jsons(["attr_add", ele, "target_lower_cardinality", trgt_card[0]])}
  189. ));
  190. attrib_creation_promises.push(ModelVerseConnector.get_output());
  191. attrib_creation_promises.push(ModelVerseConnector.send_command(
  192. {"data": utils.jsons(["attr_add", ele, "target_upper_cardinality", trgt_card[1]])}
  193. ));
  194. attrib_creation_promises.push(ModelVerseConnector.get_output());
  195. }
  196. }
  197. if (node.attributes != undefined) {
  198. //console.log(node);
  199. for (const [key, attrib] of Object.entries(node.attributes.value)) {
  200. //console.log(attrib);
  201. let type = attrib.type[0].toUpperCase() + attrib.type.substring(1);
  202. if (type.startsWith("ENUM")){
  203. type = "ENUM";
  204. }
  205. type = type.split("<")[0];
  206. attrib_creation_promises.push(ModelVerseConnector.send_command(
  207. {"data": utils.jsons(["define_attribute", ele, attrib.name, type])}
  208. ));
  209. attrib_creation_promises.push(ModelVerseConnector.get_output());
  210. }
  211. }
  212. }
  213. ModelVerseConnector.set_status(ModelVerseConnector.OKAY);
  214. });
  215. });
  216. });
  217. }
  218. static load_MV_model(metamodels, AS) {
  219. return new Promise(
  220. function (resolve, reject) {
  221. console.log("Load MV Model");
  222. console.log(AS);
  223. console.log(metamodels);
  224. let primary_MV_metamodel = metamodels.split(" ")[1].split(",")[0];
  225. let primary_PM_metamodel = ModelVerseConnector.MV2PM_metamodel_map[primary_MV_metamodel];
  226. console.log("MV MM: " + primary_MV_metamodel);
  227. console.log("PM MM: " + primary_PM_metamodel);
  228. let csmetamodel = ".defaultIcons";
  229. //this concrete syntax is better
  230. if (primary_MV_metamodel == "formalisms/SimpleClassDiagrams"){
  231. csmetamodel = ".umlIcons";
  232. }
  233. let metamodel = primary_PM_metamodel + csmetamodel + ".metamodel";
  234. DataUtils.loadmm(metamodel,
  235. function(){
  236. console.log("Metamodel loaded: " + metamodel);
  237. });
  238. let model_elements = [];
  239. let model_links = [];
  240. let model_links_dict = {};
  241. let model_attrib_types = [];
  242. let model_attribs = {};
  243. //class name, etc.
  244. let model_properties = {};
  245. for (const obj of Object.values(AS)) {
  246. let obj_type = obj["__type"];
  247. let name = obj["name"];
  248. if (name == undefined){
  249. name = obj_type;
  250. }
  251. if (obj_type == "SimpleAttribute"){
  252. model_attrib_types.push(name);
  253. continue;
  254. }
  255. let src = obj["__source"];
  256. let trgt = obj["__target"];
  257. let add_properties = true;
  258. //console.log("obj " + obj_type + " " + name + " = " + src + " - " + trgt);
  259. if (src == undefined && trgt == undefined){
  260. model_elements.push([name, obj_type]);
  261. }else{
  262. if (obj_type == "AttributeLink"){//model_attrib_types.includes(trgt)){
  263. if (model_attribs[src] == undefined){
  264. model_attribs[src] = [];
  265. }
  266. model_attribs[src].push([name, trgt]);
  267. add_properties = false;
  268. }else{
  269. model_links.push([obj_type, src, trgt, obj["__id"]]);
  270. model_links_dict[obj["__id"]] = [src, trgt];
  271. }
  272. }
  273. if (add_properties) {
  274. for (let [prop_name, prop_value] of Object.entries(obj)) {
  275. if (prop_name.startsWith("__")) {
  276. continue;
  277. }
  278. if (prop_value == null){
  279. continue;
  280. }
  281. if (model_properties[name] == undefined) {
  282. model_properties[name] = [];
  283. }
  284. if (prop_name.endsWith("_cardinality")){
  285. let dest = undefined;
  286. let lower_upper = prop_name.split("_")[1];
  287. lower_upper = (lower_upper == "lower")? "min":"max";
  288. if (prop_name.startsWith("source")){
  289. dest = model_links_dict[name][0];
  290. prop_name = "cardinality_" + lower_upper + "_" + name + "_out_";
  291. }else if (prop_name.startsWith("target")){
  292. dest = model_links_dict[name][1];
  293. prop_name = "cardinality_" + lower_upper + "_" + name + "_in_";
  294. }
  295. if (model_properties[dest] == undefined) {
  296. model_properties[dest] = [];
  297. }
  298. model_properties[dest].push([prop_name, prop_value]);
  299. //console.log(src + " :: " + prop_name + ' = ' + prop_value);
  300. continue;
  301. }
  302. // console.log(name + " :: " + prop_name + ' = ' + prop_value);
  303. model_properties[name].push([prop_name, prop_value]);
  304. }
  305. }
  306. }
  307. let ele_ids = {};
  308. //TODO: Replace with better layout
  309. let start_x = 100;
  310. let start_y = 100;
  311. let x_offset = 250;
  312. let max_x = 4;
  313. let y_offset = 200;
  314. let i = 0;
  315. let element_promises = [];
  316. for (const [name, obj_type] of model_elements){
  317. let class_type = primary_PM_metamodel + csmetamodel + "/" + obj_type + "Icon";
  318. __typeToCreate = class_type;
  319. element_promises.push(new Promise(function(resolve, reject){
  320. let updateClass =
  321. function(status, resp){
  322. if (Math.floor(status / 100) != 2){
  323. resolve();
  324. return;
  325. }
  326. // console.log(status);
  327. // console.log(resp);
  328. let data = JSON.parse(resp);
  329. let uri = class_type + "/" + data["data"] + ".instance";
  330. ele_ids[name] = uri;
  331. resolve();
  332. };
  333. let x_pos = start_x + Math.floor(i % max_x) * x_offset;
  334. let y_pos = start_y + Math.floor(i / max_x) * y_offset;
  335. DataUtils.create(x_pos, y_pos, updateClass);
  336. i +=1;
  337. }));
  338. }
  339. Promise.all(element_promises).then(function(){
  340. console.log("Starting link promises");
  341. let link_promises = [];
  342. for (const [obj_type, src, trgt, obj_id] of model_links){
  343. link_promises.push(new Promise(function(resolve, reject) {
  344. let source_element = ele_ids[src];
  345. let target_element = ele_ids[trgt];
  346. //skip attribute links
  347. if (obj_type == "AttributeLink"){
  348. resolve();
  349. return;
  350. }
  351. if (source_element == undefined || target_element == undefined) {
  352. console.log("ERROR: Can't create link '" + obj_type + "' between " + src + " and " + trgt);
  353. resolve();
  354. return;
  355. }
  356. let connectionType = primary_PM_metamodel + csmetamodel + "/" + obj_type + "Link.type";
  357. let link_create_callback = function(status, resp){
  358. // console.log(status);
  359. // console.log(resp);
  360. let id = JSON.parse(resp)["data"];
  361. let assoc_id = connectionType.replace(".type", "/") + id + ".instance";
  362. // console.log(obj_id + " = " + assoc_id);
  363. ele_ids[obj_id] = assoc_id;
  364. resolve();
  365. };
  366. console.log(connectionType);
  367. HttpUtils.httpReq(
  368. 'POST',
  369. HttpUtils.url(connectionType, __NO_USERNAME),
  370. {
  371. 'src': source_element,
  372. 'dest': target_element,
  373. 'pos': undefined,
  374. 'segments': undefined
  375. },
  376. link_create_callback);
  377. }));
  378. }
  379. Promise.all(link_promises).then(function(){
  380. console.log("Start properties");
  381. for (const [ele, properties] of Object.entries(model_properties)) {
  382. let uri = ele_ids[ele];
  383. if (uri == undefined) {
  384. console.log("Uri not found for element: " + ele);
  385. continue;
  386. }
  387. // console.log("Element: " + ele + " = uri: " + uri);
  388. let changes = {};
  389. let cardinalities = [];
  390. let card_dict = {};
  391. for (const [key, value] of Object.entries(properties)) {
  392. // console.log(value[0] + " = ");
  393. // console.log(value[1]);
  394. //TODO: Fix this
  395. if (value[0].includes("constraint")) {
  396. continue;
  397. }
  398. if (value[0].startsWith("cardinality")) {
  399. let minmax = value[0].split("_")[1];
  400. let assoc_name = value[0].split("_")[2];
  401. let dir = value[0].split("_")[3];
  402. // console.log("Card:");
  403. // console.log(minmax + " " + assoc_name + " " + dir);
  404. let found_card = false;
  405. for (let [key, existing_card] of Object.entries(cardinalities)){
  406. if (existing_card["type"] == assoc_name){
  407. found_card = true;
  408. cardinalities[key][minmax] = value[1];
  409. }
  410. }
  411. if (!found_card)
  412. {
  413. let new_card = {
  414. "dir" : dir,
  415. "type" : assoc_name
  416. };
  417. new_card[minmax] = value[1];
  418. cardinalities.push(new_card);
  419. }
  420. }else {
  421. //all other properties
  422. changes[value[0]] = value[1];
  423. }
  424. }
  425. if (cardinalities.length > 0) {
  426. changes["cardinalities"] = cardinalities;
  427. }
  428. DataUtils.update(uri, changes);
  429. }
  430. console.log("Start attributes");
  431. for (const [ele, attributes] of Object.entries(model_attribs)){
  432. let uri = ele_ids[ele];
  433. if (uri == undefined){
  434. console.log("Uri not found for element: " + ele);
  435. continue;
  436. }
  437. let attrib_changes = [];
  438. // console.log("Element: " + ele + " = uri: " + uri);
  439. for (const[key, value] of attributes){
  440. //TODO: Make attributes valid PM types
  441. let pm_value = value.toLowerCase();
  442. if (pm_value == "natural" || pm_value == "integer"){
  443. pm_value = "int";
  444. }
  445. // console.log(key + " = " + pm_value);
  446. let attrib_change = {
  447. "name": key,
  448. "type" : pm_value
  449. };
  450. attrib_changes.push(attrib_change);
  451. }
  452. DataUtils.update(uri, {"attributes" : attrib_changes});
  453. }
  454. });
  455. });
  456. resolve();
  457. });
  458. }
  459. /*********COMMUNICATION FUNCTIONS**********/
  460. static send_command(param_dict) {
  461. return new Promise(
  462. function (resolve, reject) {
  463. let callback = function (status, resp) {
  464. if (utils.isHttpSuccessCode(status)) {
  465. //console.log("send_command Resolve: " + resp);
  466. resolve(resp);
  467. } else {
  468. console.log("send_command Reject: " + resp);
  469. reject(resp);
  470. }
  471. };
  472. if (!("op" in param_dict)) {
  473. param_dict["op"] = "set_input";
  474. }
  475. if (!("taskname" in param_dict)) {
  476. param_dict["taskname"] = ModelVerseConnector.taskname;
  477. }
  478. let params = "";
  479. for (const [key, value] of Object.entries(param_dict)) {
  480. params += key + "=" + value + "&";
  481. }
  482. //take off last &
  483. params = params.slice(0, -1);
  484. console.log("Sending: " + params);
  485. HttpUtils.httpReq("POST", ModelVerseConnector.address,
  486. params,
  487. callback
  488. );
  489. });
  490. }
  491. static get_output(clbk) {
  492. return new Promise(
  493. function (resolve, reject) {
  494. let callback = function (status, resp) {
  495. if (utils.isHttpSuccessCode(status)) {
  496. console.log("get_output Resolve: " + resp);
  497. if (clbk != undefined && typeof clbk == "function"){
  498. clbk(resp);
  499. }
  500. resolve(resp);
  501. } else {
  502. console.log("get_output reject: " + resp);
  503. reject(resp);
  504. }
  505. };
  506. let params = "op=get_output&taskname=" + ModelVerseConnector.taskname;
  507. HttpUtils.httpReq("POST", ModelVerseConnector.address,
  508. params,
  509. callback
  510. );
  511. }
  512. );
  513. }
  514. /*********END COMMUNICATION FUNCTIONS**********/
  515. /*********WRAPPER FUNCTIONS**********/
  516. static connect(username_param, password_param) {
  517. console.log("Connecting to: " + ModelVerseConnector.address);
  518. ModelVerseConnector.set_status(ModelVerseConnector.WORKING);
  519. let username = username_param || "admin";
  520. let password = password_param || "admin";
  521. let username_params = {
  522. "value": "\"" + username + "\""
  523. };
  524. let password_params = {
  525. "value": "\"" + password + "\""
  526. };
  527. let quiet_mode_params = {
  528. "value": "\"quiet\""
  529. };
  530. this.get_output().then(
  531. function(data){
  532. data = data.replace(/"/g, "");
  533. ModelVerseConnector.taskname = data;
  534. }
  535. )
  536. .then(() => this.send_command(username_params)).then(this.get_output)
  537. .then(() => this.send_command(password_params)).then(this.get_output)
  538. .then(() => this.send_command(quiet_mode_params)).then(this.get_output)
  539. .then(this.get_output)
  540. .then(function () {
  541. ModelVerseConnector.set_status(ModelVerseConnector.OKAY);
  542. })
  543. .catch(
  544. function () {
  545. WindowManagement.openDialog(_ERROR, 'failed to login to the ModelVerse!');
  546. ModelVerseConnector.set_status(ModelVerseConnector.ERROR);
  547. }
  548. );
  549. };
  550. //TODO: Cache this data if too slow
  551. static async get_files_in_folder(folder_name){
  552. return await ModelVerseConnector.model_list(folder_name);
  553. }
  554. static model_list(folder_name){
  555. return new Promise(function(resolve, reject) {
  556. console.log("Listing models in: '" + folder_name + "'");
  557. let folder_param = folder_name;
  558. //fix slashes on filename
  559. if (folder_param.endsWith("/")){
  560. folder_param = folder_param.slice(0, -1);
  561. }
  562. if (folder_param.startsWith("/")){
  563. folder_param = folder_param.slice(1);
  564. }
  565. let model_types = {
  566. "data": utils.jsons(["model_list", folder_param])
  567. };
  568. ModelVerseConnector.send_command(model_types).then(ModelVerseConnector.get_output)
  569. .then(function (data) {
  570. let files = [];
  571. data = data.replace("Success: ", "");
  572. let new_files = JSON.parse(data).split("\n");
  573. for (let i in new_files) {
  574. let file = new_files[i];
  575. files.push(folder_name + file);
  576. }
  577. files.sort();
  578. resolve(files);
  579. });
  580. });
  581. }
  582. static choose_model(status, model_to_save){
  583. console.log("Choosing model: ");
  584. if (status != undefined && status != 200){
  585. ModelVerseConnector.set_status(ModelVerseConnector.ERROR);
  586. return;
  587. };
  588. let loading_mode = (model_to_save == undefined);
  589. let folders = [""];
  590. let files = [];
  591. ModelVerseConnector.set_status(ModelVerseConnector.WORKING);
  592. //if editing a model, exit it
  593. if (ModelVerseConnector.curr_model){
  594. let command = {"data": utils.jsons(["exit"])};
  595. this.send_command(command).then(this.get_output)
  596. .then(function(data){
  597. ModelVerseConnector.curr_model = null;
  598. });
  599. }
  600. let startDir = "/";
  601. let fileb = FileBrowser.getFileBrowser(ModelVerseConnector.get_files_in_folder, false, !loading_mode, startDir);
  602. let feedback = GUIUtils.getTextSpan('', "feedback");
  603. let title = "ModelVerse Explorer";
  604. let callback = function (filenames) {
  605. //fix slashes on filename
  606. // if (filenames[0].endsWith("/")){
  607. // filenames[0] = filenames[0].slice(0, -1);
  608. // }
  609. if (filenames[0].startsWith("/")){
  610. filenames[0] = filenames[0].slice(1);
  611. }
  612. if (loading_mode) {
  613. ModelVerseConnector.load_model(filenames[0]);
  614. }else{
  615. ModelVerseConnector.save_model(filenames[0], model_to_save);
  616. }
  617. };
  618. let folder_buttons = $('<div>');
  619. let new_folder_b = $('<button>');
  620. new_folder_b.attr('id', 'new_folder')
  621. .html('new folder')
  622. .click(function (ev) {
  623. let folder_name = prompt("please fill in a name for the folder");
  624. if (folder_name == null) {
  625. return;
  626. }
  627. folder_name = folder_name.replace(/^\s+|\s+$/g, ''); // trim
  628. if (!folder_name.match(/^[a-zA-Z0-9_\s]+$/i)) {
  629. feedback.html("invalid folder name: " + folder_name);
  630. } else {
  631. let full_folder_name = fileb['getcurrfolder']() + folder_name;
  632. console.log("Creating: " + full_folder_name);
  633. let mk_folder_command = {
  634. "data": utils.jsons(["folder_create", full_folder_name])
  635. };
  636. ModelVerseConnector.send_command(mk_folder_command).then(ModelVerseConnector.get_output)
  637. .then(function (data) {
  638. console.log("Got data: " + data);
  639. });
  640. }
  641. });
  642. folder_buttons.append(new_folder_b);
  643. GUIUtils.setupAndShowDialog(
  644. [fileb['filebrowser'], loading_mode?null:folder_buttons, null, feedback],
  645. function () {
  646. let value = [fileb['getselection']()];
  647. if (value.length > 0 && value[0] != "" && startDir) {
  648. __setRecentDir(startDir, value[0].substring(0, value[0].lastIndexOf('/') + 1));
  649. }
  650. return value;
  651. },
  652. __TWO_BUTTONS,
  653. title,
  654. callback);
  655. ModelVerseConnector.set_status(ModelVerseConnector.OKAY);
  656. }
  657. static load_model(model_name) {
  658. let metamodel = "formalisms/SimpleClassDiagrams";
  659. console.log("Loading model: " + model_name);
  660. ModelVerseConnector.set_status(ModelVerseConnector.WORKING);
  661. ModelVerseConnector.curr_model = model_name;
  662. //get AS for model
  663. let model_types_command = {
  664. "data": utils.jsons(["model_types", model_name])
  665. };
  666. let model_modify = {
  667. "data": utils.jsons(["model_modify", model_name, metamodel])
  668. };
  669. let model_dump = {
  670. "data": utils.jsons(["JSON"])
  671. };
  672. let model_types = null;
  673. //AS COMMANDS
  674. this.send_command(model_types_command).then(this.get_output)
  675. .then(function(data){
  676. console.log("model_types");
  677. console.log(data);
  678. model_types = data;
  679. })
  680. .then(this.send_command(model_modify)).then(this.get_output)
  681. .then(function(data){
  682. console.log("model_modify");
  683. console.log(data);
  684. })
  685. .then(this.send_command(model_dump)).then(this.get_output)
  686. .then(function(data){
  687. data = data.replace("Success: ", "");
  688. let AS = eval(JSON.parse(data));
  689. ModelVerseConnector.load_MV_model(model_types, AS)
  690. })
  691. .then(function () {
  692. ModelVerseConnector.set_status(ModelVerseConnector.OKAY);
  693. })
  694. .catch(
  695. function (err) {
  696. console.log("Error with model loading!");
  697. console.log(err);
  698. ModelVerseConnector.set_status(ModelVerseConnector.ERROR);
  699. }
  700. );
  701. }
  702. /*********END WRAPPER FUNCTIONS**********/
  703. }