Explorar o código

Merge branch 'master' of bentley/AToMPM into bentleyscommits

simon %!s(int64=6) %!d(string=hai) anos
pai
achega
6c7401fa1e

+ 1 - 0
README.md

@@ -19,6 +19,7 @@ To install AToMPM, follow these steps:
         * For Python2: `pip install six`
         * For Python3: `pip3 install six`
 * Download and install node.js
+    * Required version: >= 8.0
     * Use a package manager on Linux
     * Or visit https://nodejs.org/en/download/
 * Download and unzip the source files for the newest AToMPM release from https://msdl.uantwerpen.be/git/simon/AToMPM/releases

+ 68 - 60
___fs++.js

@@ -9,8 +9,8 @@
   	provide higher-level functions that those provided by nodejs' fs module */
 
 var _cp = require('child_process'),
-	 _os = require('os'),
-     _fs = require('fs');
+	_os = require('os'),
+	_fs = require('fs');
 
 
 /* NOTE:: because microsoft has apparently diversified into hiring comedians,
@@ -18,6 +18,10 @@ var _cp = require('child_process'),
 exports.cp =
 	function(src,dest,callback)
 	{
+		//guard against injection
+		src = src.split(';')[0];
+		dest = dest.split(';')[0];
+
 		switch(_os.type())
 		{
 			case 'Windows_NT' :
@@ -30,7 +34,7 @@ exports.cp =
 							callback(err,stdout,stderr);
 					});
 				break;
-				
+
 			case 'Linux'  :
 			case 'Darwin' :
 				_cp.exec('cp -R "'+src+'" "'+dest+'"',callback);
@@ -51,6 +55,9 @@ exports.cp =
 exports.findfiles =
 	function(dir,callback)
 	{
+		//guard against injection
+		dir = dir.split(';')[0];
+
 		switch(_os.type())
 		{
 			case 'Windows_NT' :
@@ -61,27 +68,30 @@ exports.findfiles =
 							callback(err,stdout,stderr);
 						else
 						{
-							var windir = (dir.charAt(0)=='.' ? dir.substring(1) : dir).
-												replace(/\//g,'\\'),
-								 paths  = stdout.split('\r\n').map(
+							let windir = (dir.charAt(0)=='.' ? dir.substring(1) : dir).
+								replace(/\//g,'\\'),
+								paths  = stdout.split('\r\n').map(
 									function(path)
 									{
-										var newpath = dir+path.substring(
-														path.indexOf(windir)+windir.length).
-													  replace(/\\/g,'/');
-                                        try {
-                                            if (_fs.lstatSync(path).isDirectory()) {
-                                                newpath = newpath + '/';
-                                            }
-                                        } catch (e) {}
-                                        return newpath;
+										let newpath = dir+path.substring(
+											path.indexOf(windir)+windir.length).
+										replace(/\\/g,'/');
+										try {
+											if (_fs.lstatSync(path).isDirectory()) {
+												newpath = newpath + '/';
+											}
+										} catch (e) {
+											//console.log("Error!");
+											//console.log(e);
+										}
+										return newpath;
 									});
 							paths.pop();
 							callback(err,paths.join('\n'),stderr);
 						}
 					});
 				break;
-				
+
 			case 'Linux'  :
 			case 'Darwin' :
 				_cp.exec('find "'+dir+'"',
@@ -90,14 +100,14 @@ exports.findfiles =
 						if( err )
 							callback(err,stdout,stderr);
 						else {
-                            var paths = stdout.slice(0,-1),
-                                newpaths = paths.split('\n').map(function(path) {
-                                    if (_fs.lstatSync(path).isDirectory()) {
-                                        return path + "/";
-                                    } else return path;
-                                });
+							let paths = stdout.slice(0,-1),
+								newpaths = paths.split('\n').map(function(path) {
+									if (_fs.lstatSync(path).isDirectory()) {
+										return path + "/";
+									} else return path;
+								});
 							callback(err,newpaths.join('\n'),stderr);
-                        }
+						}
 					});
 				break;
 
@@ -113,15 +123,18 @@ exports.findfiles =
 exports.mkdirs =
 	function(dir,callback)
 	{
-        var split_dir = dir.split('/'),
-            curr_dir = '';
-        for (var i in split_dir) {
-            curr_dir += split_dir[i] + '/';
-            if (!_fs.existsSync(curr_dir)) {
-                _fs.mkdir(curr_dir, 484, function(err) {if (err) {if (err.code != 'EEXIST') callback(err);}});
-            }
-        }
-        callback();
+		//guard against injection
+		dir = dir.split(';')[0];
+
+		let split_dir = dir.split('/'),
+			curr_dir = '';
+		for (let i in split_dir) {
+			curr_dir += split_dir[i] + '/';
+			if (!_fs.existsSync(curr_dir)) {
+				_fs.mkdir(curr_dir, 484, function(err) {if (err) {if (err.code != 'EEXIST') callback(err);}});
+			}
+		}
+		callback();
 	};
 
 
@@ -129,8 +142,12 @@ exports.mkdirs =
 exports.mv =
 	function(src,dest,callback)
 	{
-        var split_string = src.split('/');
-        _fs.rename(src, dest + split_string[split_string.length-1],callback);
+		//guard against injection
+		src = src.split(';')[0];
+		dest = dest.split(';')[0];
+
+		let split_string = src.split('/');
+		_fs.rename(src, dest + split_string[split_string.length-1],callback);
 	};
 
 
@@ -138,37 +155,28 @@ exports.mv =
 exports.rmdirs =
 	function(dir,callback)
 	{
-		switch(_os.type())
-		{
-			case 'Windows_NT' :
-				_cp.exec('rmdir /s "'+dir+'"',callback);
-				break;
-				
-			case 'Linux'  :
-			case 'Darwin' :
-				_cp.exec('rm -rf "'+dir+'"',callback);
-				break;
+		//guard against injection
+		dir = dir.split(';')[0];
 
-			default:
-				throw 'unsupported OS :: '+_os.type();
-		}
+		_fs.rmdir(dir, callback)
 	};
 
-
-
 // http://stackoverflow.com/questions/18052762/remove-directory-which-is-not-empty
 exports.deleteFolderRecursive = function(path) {
-   if( _fs.existsSync(path) ) {
-       _fs.readdirSync(path).forEach(function(file,index){
-           var curPath = path + "/" + file;
-           if(_fs.lstatSync(curPath).isDirectory()) { // recurse
-               exports.deleteFolderRecursive(curPath);
-           } else { // delete file
-               _fs.unlinkSync(curPath);
-           }
-       });
-       _fs.rmdirSync(path);
-   }
+	//guard against injection
+	path = path.split(';')[0];
+
+	if( _fs.existsSync(path) ) {
+		_fs.readdirSync(path).forEach(function(file,index){
+			let curPath = path + "/" + file;
+			if(_fs.lstatSync(curPath).isDirectory()) { // recurse
+				exports.deleteFolderRecursive(curPath);
+			} else { // delete file
+				_fs.unlinkSync(curPath);
+			}
+		});
+		_fs.rmdirSync(path);
+	}
 };
 	
 	

+ 0 - 1
client/atompm.html

@@ -42,7 +42,6 @@
 		<script text="text/javascript" src="client/connection_utils.js"></script>
 		<script text="text/javascript" src="client/window_management.js"></script>
 		<script text="text/javascript" src="client/file_browser.js"></script>
-        <script text="text/javascript" src="client/modelverse_connector.js"></script>
 		<script text="text/javascript" src="client/query_response.js"></script>
 		<script text="text/javascript" src="client/collaboration.js"></script>
 		<script text="text/javascript" src="client/layout.js"></script>

+ 1 - 1
client/constants.js

@@ -7,7 +7,7 @@
 var __WEBPAGE__ = 'https://atompm.github.io/',
 	__RELEASE_LOC__ = "https://api.github.com/repos/AToMPM/atompm/releases/latest",
 	__DOC_WEBPAGE__ = "https://msdl.uantwerpen.be/documentation/AToMPM/index.html",
-    __VERSION__ = '0.8.1',
+    __VERSION__ = '0.8.2',
     __DEFAULT_SAVEAS		 	= '.autosave.model',
 	 __TITLE						= 'AToMPM',
 	 __EXITWARNING				= 'There are unsaved changes. Proceeding will cause'+

+ 1 - 4
client/file_browser.js

@@ -294,7 +294,6 @@ class FileBrowser{
 
                     //fnames might be a function that returns the files in
                     //the folder
-                    //bentley: the ModelVerse only examines one folder at a time
                     let file_list = fnames;
                     if (!(Array.isArray(fnames))){
                         file_list = await fnames(folder);
@@ -399,9 +398,7 @@ class FileBrowser{
                     currfolder = folder;
                 };
 
-        let file_browser_width = 120;
-        fileb.css("width", file_browser_width + 'ex')
-            .css("maxWidth", '100%');
+        fileb.css("maxWidth", '100%');
 
         navdiv.css("align", 'left');
 

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 1074
client/modelverse_connector.js


+ 0 - 333
client/modelverse_connector_rendering.js

@@ -1,333 +0,0 @@
-/* This file holds the code for rendering SimpleClassDiagrams from the ModelVerse.
-
-1) The rendering meta-model and transformation are sent to the ModelVerse.
-2) The transformation executes, creating the rendered model and returning the JSON.
-3) 'model_CS' will then contain the rendered concrete syntax
-
-This method is dependent on the meta-model being SimpleClassDiagrams.
-Therefore, this code should be put aside until a more robust rendering
-system in the ModelVerse is created.
-
-For example, it would be ideal to have a render transformation explicitly defined
-for each metamodel in the ModelVerse. Then the render_model command could just
-return the JSON for the rendered model (or just the updated portion).
-
- */
-
-class ModelVerseRenderer {
-
-    static get_CS(model_name) {
-
-        //get CS for model
-
-        let SCD = "formalisms/SimpleClassDiagrams";
-        let MM_render = "formalisms/SCD_graphical";
-        let render_trans_model = "models/render_SCD";
-        let render_MM = this.get_render_mm();
-        let render_trans_code = this.get_render_trans();
-        let render_model_add = {
-            'data': encodeURIComponent(utils.jsons(["model_add", SCD, MM_render, render_MM]))
-        };
-
-        let transformation_between = {
-            'data': encodeURIComponent(utils.jsons(["transformation_add_AL", "rendered", MM_render, "abstract", SCD, "", "rendered", MM_render, "", render_trans_model]))
-        };
-
-        let transformation_data = {
-            'data': encodeURIComponent(utils.jsons(["transformation_add_AL", render_trans_code]))
-        };
-
-        let model_rendered = {
-            'data': encodeURIComponent(utils.jsons(["model_render", model_name, render_trans_model, "models/rendered_model"]))
-        };
-
-        //CS COMMANDS
-
-        let model_CS = null;
-
-        //TODO: only need to add models if not present
-        ModelVerseConnector.send_command(render_model_add).then(ModelVerseConnector.get_output)
-            .then(ModelVerseConnector.send_command(transformation_between)).then(ModelVerseConnector.get_output)
-            .then(ModelVerseConnector.send_command({})).then(ModelVerseConnector.get_output)
-            .then(ModelVerseConnector.send_command(transformation_data)).then(ModelVerseConnector.get_output)
-            .then(ModelVerseConnector.send_command(model_rendered)).then(ModelVerseConnector.get_output)
-
-            .then(function(data){
-                // console.log("Data before: ");
-                // console.log(data);
-                data = data.replace("Success: ", "");
-                // console.log("Data after:");
-                // console.log(data);
-                model_CS = eval(JSON.parse(data));
-            });
-
-    }
-
-    static get_render_mm() {
-        let mm = "include \"primitives.alh\"\n" +
-            "\n" +
-            "SimpleAttribute Natural {}\n" +
-            "SimpleAttribute String {}\n" +
-            "SimpleAttribute Boolean {}\n" +
-            "\n" +
-            "Class GraphicalElement {\n" +
-            "    x : Natural\n" +
-            "    y : Natural\n" +
-            "    layer : Natural\n" +
-            "}\n" +
-            "\n" +
-            "Class Group : GraphicalElement {\n" +
-            "    __asid : String\n" +
-            "    dirty : Boolean\n" +
-            "}\n" +
-            "\n" +
-            "Association ConnectingLine (Group, Group) {\n" +
-            "    offsetSourceX : Natural\n" +
-            "    offsetSourceY : Natural\n" +
-            "    offsetTargetX : Natural\n" +
-            "    offsetTargetY : Natural\n" +
-            "    lineWidth : Natural\n" +
-            "    lineColour : String\n" +
-            "    arrow : Boolean\n" +
-            "    __asid : String\n" +
-            "    dirty : Boolean\n" +
-            "    layer : Natural\n" +
-            "}\n" +
-            "\n" +
-            "Class LineElement : GraphicalElement {\n" +
-            "    lineWidth : Natural\n" +
-            "    lineColour : String\n" +
-            "}\n" +
-            "\n" +
-            "Class Text : LineElement {\n" +
-            "    text : String\n" +
-            "}\n" +
-            "\n" +
-            "Class Line : LineElement {\n" +
-            "    targetX : Natural\n" +
-            "    targetY : Natural\n" +
-            "    arrow : Boolean\n" +
-            "}\n" +
-            "\n" +
-            "Class Shape : LineElement {\n" +
-            "    fillColour : String\n" +
-            "    width : Natural\n" +
-            "    height : Natural\n" +
-            "}\n" +
-            "\n" +
-            "Class Figure : GraphicalElement {\n" +
-            "    width : Natural\n" +
-            "    height : Natural\n" +
-            "}\n" +
-            "\n" +
-            "Class SVG {\n" +
-            "    data : String\n" +
-            "}\n" +
-            "\n" +
-            "Class Rectangle : Shape {\n" +
-            "}\n" +
-            "\n" +
-            "Class Ellipse : Shape {\n" +
-            "}\n" +
-            "\n" +
-            "Association contains (Group, GraphicalElement) {}\n" +
-            "Association renders (Figure, SVG) {\n" +
-            "    source_lower_cardinality = 1\n" +
-            "    target_lower_cardinality = 1\n" +
-            "    target_upper_cardinality = 1\n" +
-            "}"
-        ;
-
-        return mm;
-    }
-
-    static get_render_trans() {
-        let trans = "include \"primitives.alh\"\n" +
-            "include \"modelling.alh\"\n" +
-            "include \"object_operations.alh\"\n" +
-            "include \"utils.alh\"\n" +
-            "\n" +
-            "Boolean function main(model : Element):\n" +
-            "\tElement elements\n" +
-            "\tString class\n" +
-            "\tElement attrs\n" +
-            "\tElement attr_keys\n" +
-            "\tString attr_key\n" +
-            "\tString group\n" +
-            "\tString elem\n" +
-            "\tInteger loc\n" +
-            "\tInteger text_loc\n" +
-            "\tElement related_groups\n" +
-            "\tloc = 10\n" +
-            "\n" +
-            "\tElement groups\n" +
-            "\tgroups = dict_create()\n" +
-            "\n" +
-            "\telements = allInstances(model, \"rendered/Group\")\n" +
-            "\twhile (set_len(elements) > 0):\n" +
-            "\t\tgroup = set_pop(elements)\n" +
-            "\t\tif (set_len(allIncomingAssociationInstances(model, group, \"TracabilityClass\")) == 0):\n" +
-            "\t\t\tElement to_remove\n" +
-            "\t\t\tString elem_to_remove\n" +
-            "\t\t\tto_remove = allAssociationDestinations(model, group, \"rendered/contains\")\n" +
-            "\t\t\twhile (set_len(to_remove) > 0):\n" +
-            "\t\t\t\telem_to_remove = set_pop(to_remove)\n" +
-            "\t\t\t\tif (read_type(model, elem_to_remove) == \"rendered/Group\"):\n" +
-            "\t\t\t\t\tset_add(to_remove, elem_to_remove)\n" +
-            "\t\t\t\telse:\n" +
-            "\t\t\t\t\tmodel_delete_element(model, elem_to_remove)\n" +
-            "\t\t\tmodel_delete_element(model, group)\n" +
-            "\n" +
-            "\telements = allInstances(model, \"abstract/Class\")\n" +
-            "\twhile (set_len(elements) > 0):\n" +
-            "\t\tclass = set_pop(elements)\n" +
-            "\t\t\n" +
-            "\t\tInteger x\n" +
-            "\t\tInteger y\n" +
-            "\t\tx = loc\n" +
-            "\t\ty = 10\n" +
-            "\n" +
-            "\t\t// Check if there is already an associated element\n" +
-            "\t\tif (set_len(allOutgoingAssociationInstances(model, class, \"TracabilityClass\")) > 0):\n" +
-            "\t\t\t// Yes, but is it still clean?\n" +
-            "\t\t\tBoolean dirty\n" +
-            "\t\t\tdirty = False\n" +
-            "\n" +
-            "\t\t\trelated_groups = allAssociationDestinations(model, class, \"TracabilityClass\")\n" +
-            "\t\t\twhile (set_len(related_groups) > 0):\n" +
-            "\t\t\t\tgroup = set_pop(related_groups)\n" +
-            "\t\t\t\tif (value_eq(read_attribute(model, group, \"dirty\"), True)):\n" +
-            "\t\t\t\t\t// No, so mark all as dirty\n" +
-            "\t\t\t\t\tdirty = True\n" +
-            "\t\t\t\t\tbreak!\n" +
-            "\t\t\t\telse:\n" +
-            "\t\t\t\t\t// Yes, so just ignore this!\n" +
-            "\t\t\t\t\tcontinue!\n" +
-            "\n" +
-            "\t\t\tif (bool_not(dirty)):\n" +
-            "\t\t\t\tdict_add(groups, class, group)\n" +
-            "\t\t\t\tcontinue!\n" +
-            "\t\t\telse:\n" +
-            "\t\t\t\trelated_groups = allAssociationDestinations(model, class, \"TracabilityClass\")\n" +
-            "\t\t\t\tElement to_remove\n" +
-            "\t\t\t\tString elem_to_remove\n" +
-            "\t\t\t\twhile (set_len(related_groups) > 0):\n" +
-            "\t\t\t\t\tgroup = set_pop(related_groups)\n" +
-            "\t\t\t\t\tto_remove = allAssociationDestinations(model, group, \"rendered/contains\")\n" +
-            "\t\t\t\t\tx = create_value(read_attribute(model, group, \"x\"))\n" +
-            "\t\t\t\t\ty = create_value(read_attribute(model, group, \"y\"))\n" +
-            "\t\t\t\t\twhile (set_len(to_remove) > 0):\n" +
-            "\t\t\t\t\t\telem_to_remove = set_pop(to_remove)\n" +
-            "\t\t\t\t\t\tif (read_type(model, elem_to_remove) == \"rendered/Group\"):\n" +
-            "\t\t\t\t\t\t\tset_add(to_remove, elem_to_remove)\n" +
-            "\t\t\t\t\t\telse:\n" +
-            "\t\t\t\t\t\t\tmodel_delete_element(model, elem_to_remove)\n" +
-            "\t\t\t\t\tmodel_delete_element(model, group)\n" +
-            "\n" +
-            "\t\tattr_keys = dict_keys(getAttributeList(model, class))\n" +
-            "\t\ttext_loc = 5\n" +
-            "\n" +
-            "\t\tgroup = instantiate_node(model, \"rendered/Group\", \"\")\n" +
-            "\t\tinstantiate_attribute(model, group, \"x\", x)\n" +
-            "\t\tinstantiate_attribute(model, group, \"y\", y)\n" +
-            "\t\tinstantiate_attribute(model, group, \"__asid\", list_read(string_split_nr(class, \"/\", 1), 1))\n" +
-            "\t\tinstantiate_attribute(model, group, \"layer\", 0)\n" +
-            "\t\tdict_add(groups, class, group)\n" +
-            "\t\tloc = loc + 200\n" +
-            "\n" +
-            "\t\telem = instantiate_node(model, \"rendered/Rectangle\", \"\")\n" +
-            "\t\tinstantiate_attribute(model, elem, \"x\", 0)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"y\", 0)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"height\", 40 + set_len(getInstantiatableAttributes(model, class, \"abstract/AttributeLink\")) * 20)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"width\", 150)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineWidth\", 2) \n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineColour\", \"black\")\n" +
-            "\t\tinstantiate_attribute(model, elem, \"fillColour\", \"white\")\n" +
-            "\t\tinstantiate_attribute(model, elem, \"layer\", 1)\n" +
-            "\t\tinstantiate_link(model, \"rendered/contains\", \"\", group, elem)\n" +
-            "\n" +
-            "\t\tString multiplicities\n" +
-            "\t\tString lower_card\n" +
-            "\t\tString upper_card\n" +
-            "\t\tif (element_eq(read_attribute(model, class, \"lower_cardinality\"), read_root())):\n" +
-            "\t\t\tlower_card = \"*\"\n" +
-            "\t\telse:\n" +
-            "\t\t\tlower_card = cast_value(read_attribute(model, class, \"lower_cardinality\"))\n" +
-            "\t\tif (element_eq(read_attribute(model, class, \"upper_cardinality\"), read_root())):\n" +
-            "\t\t\tupper_card = \"*\"\n" +
-            "\t\telse:\n" +
-            "\t\t\tupper_card = cast_value(read_attribute(model, class, \"upper_cardinality\"))\n" +
-            "\t\tmultiplicities = (((\"[\" + lower_card) + \"..\") + upper_card) + \"]\"\n" +
-            "\n" +
-            "\t\telem = instantiate_node(model, \"rendered/Text\", \"\")\n" +
-            "\t\tinstantiate_attribute(model, elem, \"x\", 5)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"y\", 3)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineWidth\", 1)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineColour\", \"black\")\n" +
-            "\t\tif (element_neq(read_attribute(model, class, \"name\"), read_root())):\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"text\", string_join(read_attribute(model, class, \"name\"), \"  \" + multiplicities))\n" +
-            "\t\telse:\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"text\", \"(unnamed) \" + multiplicities)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"layer\", 2)\n" +
-            "\t\tinstantiate_link(model, \"rendered/contains\", \"\", group, elem)\n" +
-            "\n" +
-            "\t\telem = instantiate_node(model, \"rendered/Line\", \"\")\n" +
-            "\t\tinstantiate_attribute(model, elem, \"x\", 0)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"y\", 20)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"targetX\", 150)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"targetY\", 20)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineWidth\", 1)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineColour\", \"black\")\n" +
-            "\t\tinstantiate_attribute(model, elem, \"arrow\", False)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"layer\", 2)\n" +
-            "\t\tinstantiate_link(model, \"rendered/contains\", \"\", group, elem)\n" +
-            "\n" +
-            "\t\tattrs = getInstantiatableAttributes(model, class, \"abstract/AttributeLink\")\n" +
-            "\t\tattr_keys = dict_keys(attrs)\n" +
-            "\t\twhile (dict_len(attr_keys) > 0):\n" +
-            "\t\t\tattr_key = set_pop(attr_keys)\n" +
-            "\t\t\telem = instantiate_node(model, \"rendered/Text\", \"\")\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"x\", 5)\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"y\", text_loc + 20)\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"lineWidth\", 1)\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"lineColour\", \"black\")\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"text\", (attr_key + \" : \") + cast_string(list_read(string_split_nr(attrs[attr_key], \"/\", 1), 1)))\n" +
-            "\t\t\tinstantiate_attribute(model, elem, \"layer\", 2)\n" +
-            "\t\t\tinstantiate_link(model, \"rendered/contains\", \"\", group, elem)\n" +
-            "\t\t\ttext_loc = text_loc + 15\n" +
-            "\n" +
-            "\t\tinstantiate_link(model, \"TracabilityClass\", \"\", class, group)\n" +
-            "\n" +
-            "\t// Flush all associations\n" +
-            "\telements = allInstances(model, \"rendered/ConnectingLine\")\n" +
-            "\twhile (set_len(elements) > 0):\n" +
-            "\t\tclass = set_pop(elements)\n" +
-            "\t\tmodel_delete_element(model, class)\n" +
-            "\n" +
-            "\t// Rerender associations\n" +
-            "\telements = allInstances(model, \"abstract/Association\")\n" +
-            "\twhile (set_len(elements) > 0):\n" +
-            "\t\tclass = set_pop(elements)\n" +
-            "\n" +
-            "\t\tattr_keys = dict_keys(getAttributeList(model, class))\n" +
-            "\n" +
-            "\t\telem = instantiate_link(model, \"rendered/ConnectingLine\", \"\", groups[readAssociationSource(model, class)], groups[readAssociationDestination(model, class)])\n" +
-            "\t\tinstantiate_attribute(model, elem, \"offsetSourceX\", 75)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"offsetSourceY\", 30)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"offsetTargetX\", 75)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"offsetTargetY\", 30)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineWidth\", 1)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"lineColour\", \"black\")\n" +
-            "\t\tinstantiate_attribute(model, elem, \"arrow\", True)\n" +
-            "\t\tinstantiate_attribute(model, elem, \"__asid\", list_read(string_split_nr(class, \"/\", 1), 1))\n" +
-            "\t\tinstantiate_attribute(model, elem, \"layer\", 0)\n" +
-            "\t\tlog(\"Real ASID: \" + cast_value(class))\n" +
-            "\t\tlog(\"Found ASID \" + cast_value(list_read(string_split_nr(class, \"/\", 1), 1)))\n" +
-            "\t\tinstantiate_link(model, \"rendered/contains\", \"\", group, elem)\n" +
-            "\n" +
-            "\treturn True!";
-
-        return trans;
-    }
-
-}

+ 1 - 1
doc/conf.py

@@ -26,7 +26,7 @@ author = 'The AToMPM Team'
 # The short X.Y version
 version = ''
 # The full version, including alpha/beta/rc tags
-release = '0.8.1'
+release = '0.8.2'
 
 
 # -- General configuration ---------------------------------------------------

+ 0 - 15
doc/toolbars_and_plugins.rst

@@ -59,18 +59,3 @@ To export metamodels or models in AToMPM, follow these steps:
 
 10. If you want to use the exported file in Eclipse, you have to register the metamodel.
 
-
-ModelVerse Toolbar
-------------------
-
-.. warning:: The ModelVerse toolbar is currently in an alpha state. It is only intended as a prototype and should not be used for everyday use, as data loss is certain to occur.
-
-The ModelVerse toolbar is intended to allow for the user to load and save models to/from AToMPM to the Modelverse. 
-
-.. warning:: Currently, only metamodels in the SimpleClassDiagram formalism can be loaded and saved, along with instance models.
-
-The first button on the toolbar connects to a running ModelVerse instance running on the current machine.
-
-The second button loads a model from the ModelVerse into the current AToMPM canvas.
-
-The third button saves the current AToMPM model to the ModelVerse.

+ 23 - 5
httpwsd.js

@@ -542,9 +542,16 @@ var httpserver = _http.createServer(
 			{
 				req.setEncoding('utf8');
 
-				var reqData = '',
+				let reqData = '',
 					 tmpzip	= 'upload'+Date.now()+'.zip',
 					 destdir	= './users/'+url.pathname.match(/(.*)\.file$/)[1]+'/';
+
+				if( url.pathname.contains("..") || url.pathname.contains(";") ) {
+					__respond(resp, 404,
+						'invalid pathname, no semicolons or .. allowed :: ' + url.pathname);
+					return;
+				}
+
 				req.addListener("data", function(chunk) {reqData += chunk;});
 				req.addListener("end", 
 					function() 
@@ -570,7 +577,10 @@ var httpserver = _http.createServer(
 														__respond(resp,500,String(err));
 													else
 														__respond(resp,200);
-													_fs.unlink(destdir+tmpzip);
+													_fs.unlink(destdir+tmpzip, function(err){
+														console.log("Unlinked " + destdir + tmpzip);
+														}
+													);
 												});
 										});
 							});
@@ -580,12 +590,18 @@ var httpserver = _http.createServer(
 			/* serve specified file/folder within a zip file */ 
 			else if( req.method == 'GET' && url.pathname.match(/\.file$/) )
 			{
-				var matches  = url.pathname.match(/^\/(.*?)\/(.*)\.file$/),
+				let matches  = url.pathname.match(/^\/(.*?)\/(.*)\.file$/),
 					 username = matches[1],
  					 fname 	 = './'+matches[2],
 					 userdir	 = './users/'+username+'/',
 					 tmpzip	 = 'download'+Date.now()+'.zip';
 
+				if( username.contains("..") || username.contains(";") ) {
+					__respond(resp, 404,
+						'invalid username, no colons or .. allowed :: ' + username);
+					return;
+				}
+
 				_fs.exists(userdir+fname,
 					function(exists)
 					{
@@ -599,14 +615,16 @@ var httpserver = _http.createServer(
 									if( err )
 										__respond(resp,500,String(err));
 									else
-										_fs.readFile(userdir+tmpzip,'binary',
+										_fs.readFile(userdir+tmpzip,
 											function(err, data)
 											{
 												__respond(resp,200,'',data,
 													{'Content-Type':'application/zip',
 													 'Content-Disposition':
 													 	'attachment; filename="'+tmpzip+'"'});
-												_fs.unlink(userdir+tmpzip);
+												_fs.unlink(userdir+tmpzip, function(err){
+													console.log("Unlinked " + userdir+tmpzip);
+												});
 											});
 								});
 					});

+ 3 - 4
nightwatch.conf.js

@@ -3,9 +3,8 @@
 *  See COPYING, COPYING.lesser, and README.md for full details
 */
 
-const seleniumServer = require("selenium-server");
 const chromedriver = require("chromedriver");
-
+const selenium_server = require("selenium-server");
 
 
 module.exports = {
@@ -17,8 +16,8 @@ module.exports = {
   "globals_path" : "",
 
   "selenium" : {
-    "start_process" : true,
-    "server_path" : seleniumServer.path,
+    "start_process" : false,
+    "server_path" : selenium_server.path,
     "log_path" : "",
     "port" : 4444,
     "cli_args" : {

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 455 - 399
package-lock.json


+ 5 - 5
package.json

@@ -1,6 +1,6 @@
 {
   "name": "atompm",
-  "version": "0.8.1",
+  "version": "0.8.2",
   "description": "A Tool for Multi-Paradigm Modelling",
   "license": "LGPL-3.0-only",
   "homepage": "https://atompm.github.io/",
@@ -16,10 +16,10 @@
     "socket.io-client": "^0.9.16"
   },
   "devDependencies": {
-    "chromedriver": "^2.43.1",
-    "glob": "^7.1.2",
-    "nightwatch": "^0.9.21",
-    "selenium-server": "^3.13.0"
+    "chromedriver": "^2.46.0",
+    "glob": "^7.1.4",
+    "nightwatch": "^1.1.13",
+    "selenium-server": "3.141.59"
   },
   "scripts": {
     "test": "./run_tests.sh"

+ 7 - 6
packaging/package.sh

@@ -5,17 +5,18 @@
 #   i. In AToMPM - client/constants.js
 #   ii. In documentation - doc/conf.py
 #   iii. In Node - package.json
-#2. Create a new release on GitHub
-#3. The tag should be something like v0.8.0
-#4. Run this script, which will download the latest tagged version
+#2. Push these changes to GitHub
+#3. Create a new release on GitHub
+#4. The tag should be something like v0.8.0
+#5. Run this script, which will download the latest tagged version
 #   and package everything
 #   - Run it for the Python2 and the Python3 version
 #   - Fix up the files in the package
 #        - Delete the unused Python directory in each zip
-#5. Upload the package .zip to the release on GitHub
-#6. Publish to npm repo
+#6. Upload the package .zip to the release on GitHub
+#7. Publish to npm repo
 
-version="v0.8.1-rc4"
+version="v0.8.2"
 
 package_python3=true
 

+ 14 - 3
run_tests.sh

@@ -29,15 +29,26 @@ if ! kill -0 "$mtpid"; then
     exit $mt_status
 fi
 
-echo "Starting tests..."
+echo "Starting Selenium server."
+java -jar "./node_modules/selenium-server/lib/runner/selenium-server-standalone-3.141.59.jar" &
+seleniumpid=$!
+sleep 3
+
+#check if model transformer is dead
+if ! kill -0 "$seleniumpid"; then
+    wait seleniumpid
+    se_status=$?
+    exit $se_status
+fi
 
-#start nightwatch tests
-nightwatch
 
+echo "Starting tests..."
+nightwatch
 
 echo "Stopping server and mt script..."
 kill "$serverpid"
 kill "$mtpid"
+kill "$seleniumpid"
 
 
 

+ 0 - 610
users/(default)/Toolbars/ModelVerse/ModelVerse.buttons.model

@@ -1,610 +0,0 @@
-{
-	"csm": {
-		"nodes": {
-			"0": {
-				"typename": {
-					"type": "string",
-					"value": "ButtonIcon"
-				},
-				"position": {
-					"type": "list<double>",
-					"value": [
-						499,
-						271
-					]
-				},
-				"orientation": {
-					"type": "double",
-					"value": 0
-				},
-				"scale": {
-					"type": "list<double>",
-					"value": [
-						1,
-						1
-					]
-				},
-				"mapper": {
-					"type": "code",
-					"value": ""
-				},
-				"parser": {
-					"type": "code",
-					"value": ""
-				},
-				"$contents": {
-					"type": "map<string,*>",
-					"value": {
-						"nodes": {
-							"1": {
-								"width": {
-									"type": "double",
-									"value": "120"
-								},
-								"height": {
-									"type": "double",
-									"value": "50"
-								},
-								"cornerRadius": {
-									"type": "double",
-									"value": "25"
-								},
-								"style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#af0000",
-										"stroke-dasharray": "",
-										"fill": "#000000",
-										"fill-opacity": 0.05,
-										"stroke-width": 2
-									}
-								},
-								"mapper": {
-									"type": "code",
-									"value": ""
-								},
-								"parser": {
-									"type": "code",
-									"value": ""
-								},
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Rectangle",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										0,
-										0
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								}
-							},
-							"2": {
-								"textContent": {
-									"type": "string",
-									"value": "connectMV"
-								},
-								"style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#000000",
-										"stroke-dasharray": "",
-										"fill": "#ffffff",
-										"fill-opacity": 0.75,
-										"font-size": "13px",
-										"stroke-width": 1
-									}
-								},
-								"mapper": {
-									"type": "code",
-									"value": "({\"textContent\":getAttr(\"name\")})"
-								},
-								"parser": {
-									"type": "code",
-									"value": "({\"name\":getAttr(\"textContent\")})"
-								},
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Text",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										10,
-										13
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								}
-							},
-							"3": {
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Contain",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										17.74899850809561,
-										12.998998508095553
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								},
-								"link-style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#00ffff",
-										"stroke-dasharray": "",
-										"stroke-opacity": 0.1,
-										"arrow-start": "none",
-										"arrow-end": "classic-wide-long"
-									}
-								}
-							}
-						},
-						"edges": [
-							{
-								"src": "1",
-								"dest": 3
-							},
-							{
-								"src": 3,
-								"dest": "2"
-							}
-						]
-					}
-				},
-				"$asuri": {
-					"type": "string",
-					"value": "/Formalisms/__Utilities__/Buttons/Buttons/Button/0.instance"
-				},
-				"$type": "/Formalisms/__Utilities__/Buttons/Buttons.defaultIcons/ButtonIcon"
-			},
-			"1": {
-				"typename": {
-					"type": "string",
-					"value": "ButtonIcon"
-				},
-				"position": {
-					"type": "list<double>",
-					"value": [
-						708,
-						315
-					]
-				},
-				"orientation": {
-					"type": "double",
-					"value": 0
-				},
-				"scale": {
-					"type": "list<double>",
-					"value": [
-						1,
-						1
-					]
-				},
-				"mapper": {
-					"type": "code",
-					"value": ""
-				},
-				"parser": {
-					"type": "code",
-					"value": ""
-				},
-				"$contents": {
-					"type": "map<string,*>",
-					"value": {
-						"nodes": {
-							"1": {
-								"width": {
-									"type": "double",
-									"value": "120"
-								},
-								"height": {
-									"type": "double",
-									"value": "50"
-								},
-								"cornerRadius": {
-									"type": "double",
-									"value": "25"
-								},
-								"style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#af0000",
-										"stroke-dasharray": "",
-										"fill": "#000000",
-										"fill-opacity": 0.05,
-										"stroke-width": 2
-									}
-								},
-								"mapper": {
-									"type": "code",
-									"value": ""
-								},
-								"parser": {
-									"type": "code",
-									"value": ""
-								},
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Rectangle",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										0,
-										0
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								}
-							},
-							"2": {
-								"textContent": {
-									"type": "string",
-									"value": "loadModel"
-								},
-								"style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#000000",
-										"stroke-dasharray": "",
-										"fill": "#ffffff",
-										"fill-opacity": 0.75,
-										"font-size": "13px",
-										"stroke-width": 1
-									}
-								},
-								"mapper": {
-									"type": "code",
-									"value": "({\"textContent\":getAttr(\"name\")})"
-								},
-								"parser": {
-									"type": "code",
-									"value": "({\"name\":getAttr(\"textContent\")})"
-								},
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Text",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										10,
-										13
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								}
-							},
-							"3": {
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Contain",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										17.74899850809561,
-										12.998998508095553
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								},
-								"link-style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#00ffff",
-										"stroke-dasharray": "",
-										"stroke-opacity": 0.1,
-										"arrow-start": "none",
-										"arrow-end": "classic-wide-long"
-									}
-								}
-							}
-						},
-						"edges": [
-							{
-								"src": "1",
-								"dest": 3
-							},
-							{
-								"src": 3,
-								"dest": "2"
-							}
-						]
-					}
-				},
-				"$asuri": {
-					"type": "string",
-					"value": "/Formalisms/__Utilities__/Buttons/Buttons/Button/1.instance"
-				},
-				"$type": "/Formalisms/__Utilities__/Buttons/Buttons.defaultIcons/ButtonIcon"
-			},
-			"21": {
-				"typename": {
-					"type": "string",
-					"value": "ButtonIcon"
-				},
-				"position": {
-					"type": "list<double>",
-					"value": [
-						866,
-						384
-					]
-				},
-				"orientation": {
-					"type": "double",
-					"value": 0
-				},
-				"scale": {
-					"type": "list<double>",
-					"value": [
-						1,
-						1
-					]
-				},
-				"mapper": {
-					"type": "code",
-					"value": ""
-				},
-				"parser": {
-					"type": "code",
-					"value": ""
-				},
-				"$contents": {
-					"type": "map<string,*>",
-					"value": {
-						"nodes": {
-							"1": {
-								"width": {
-									"type": "double",
-									"value": "120"
-								},
-								"height": {
-									"type": "double",
-									"value": "50"
-								},
-								"cornerRadius": {
-									"type": "double",
-									"value": "25"
-								},
-								"style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#af0000",
-										"stroke-dasharray": "",
-										"fill": "#000000",
-										"fill-opacity": 0.05,
-										"stroke-width": 2
-									}
-								},
-								"mapper": {
-									"type": "code",
-									"value": ""
-								},
-								"parser": {
-									"type": "code",
-									"value": ""
-								},
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Rectangle",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										0,
-										0
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								}
-							},
-							"2": {
-								"textContent": {
-									"type": "string",
-									"value": "saveModel"
-								},
-								"style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#000000",
-										"stroke-dasharray": "",
-										"fill": "#ffffff",
-										"fill-opacity": 0.75,
-										"font-size": "13px",
-										"stroke-width": 1
-									}
-								},
-								"mapper": {
-									"type": "code",
-									"value": "({\"textContent\":getAttr(\"name\")})"
-								},
-								"parser": {
-									"type": "code",
-									"value": "({\"name\":getAttr(\"textContent\")})"
-								},
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Text",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										10,
-										13
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								}
-							},
-							"3": {
-								"$type": "/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax/Contain",
-								"position": {
-									"type": "list<double>",
-									"value": [
-										17.74899850809561,
-										12.998998508095553
-									]
-								},
-								"orientation": {
-									"type": "double",
-									"value": 0
-								},
-								"scale": {
-									"type": "list<double>",
-									"value": [
-										1,
-										1
-									]
-								},
-								"link-style": {
-									"type": "map<string,string>",
-									"value": {
-										"stroke": "#00ffff",
-										"stroke-dasharray": "",
-										"stroke-opacity": 0.1,
-										"arrow-start": "none",
-										"arrow-end": "classic-wide-long"
-									}
-								}
-							}
-						},
-						"edges": [
-							{
-								"src": "1",
-								"dest": 3
-							},
-							{
-								"src": 3,
-								"dest": "2"
-							}
-						]
-					}
-				},
-				"$asuri": {
-					"type": "string",
-					"value": "/Formalisms/__Utilities__/Buttons/Buttons/Button/21.instance"
-				},
-				"$type": "/Formalisms/__Utilities__/Buttons/Buttons.defaultIcons/ButtonIcon"
-			}
-		},
-		"edges": [],
-		"metamodels": [
-			"/Formalisms/__Utilities__/Buttons/Buttons.defaultIcons",
-			"/Formalisms/__LanguageSyntax__/SimpleClassDiagram/SimpleClassDiagram.defaultIcons",
-			"/Formalisms/__LanguageSyntax__/SimpleClassDiagram/SimpleClassDiagram.umlIcons",
-			"/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax.defaultIcons",
-			"/Formalisms/SCCD/SCCD.defaultIcons"
-		]
-	},
-	"asm": {
-		"nodes": {
-			"0": {
-				"name": {
-					"type": "string",
-					"value": "connectMV"
-				},
-				"tooltip": {
-					"type": "string",
-					"value": "(ALPHA) Connect to the ModelVerse"
-				},
-				"code": {
-					"type": "code",
-					"value": "new ModelVerseConnector();\nModelVerseConnector.connect();"
-				},
-				"$type": "/Formalisms/__Utilities__/Buttons/Buttons/Button"
-			},
-			"1": {
-				"name": {
-					"type": "string",
-					"value": "loadModel"
-				},
-				"tooltip": {
-					"type": "string",
-					"value": "(ALPHA) Load a model from the ModelVerse"
-				},
-				"code": {
-					"type": "code",
-					"value": "if (ModelVerseConnector.connected == undefined){\n    WindowManagement.openDialog(_ERROR,'Connect to the ModelVerse first');\n}else{\n    ModelVerseConnector.choose_model();\n}"
-				},
-				"$type": "/Formalisms/__Utilities__/Buttons/Buttons/Button"
-			},
-			"21": {
-				"name": {
-					"type": "string",
-					"value": "saveModel"
-				},
-				"tooltip": {
-					"type": "string",
-					"value": "(ALPHA) Save a model to the ModelVerse"
-				},
-				"code": {
-					"type": "code",
-					"value": "if (ModelVerseConnector.connected == undefined){\n    WindowManagement.openDialog(_ERROR,'Connect to the ModelVerse first');\n}else{\n    _httpReq('GET', '/current.state?wid='+_context.aswid, undefined,                \n    ModelVerseConnector.choose_model);\n}"
-				},
-				"$type": "/Formalisms/__Utilities__/Buttons/Buttons/Button"
-			}
-		},
-		"edges": [],
-		"metamodels": [
-			"/Formalisms/__Utilities__/Buttons/Buttons",
-			"/Formalisms/__LanguageSyntax__/SimpleClassDiagram/SimpleClassDiagram",
-			"/Formalisms/__LanguageSyntax__/ConcreteSyntax/ConcreteSyntax",
-			"/Formalisms/SCCD/SCCD"
-		]
-	}
-}

BIN=BIN
users/(default)/Toolbars/ModelVerse/connectMV.icon.png


BIN=BIN
users/(default)/Toolbars/ModelVerse/loadModel.icon.png


BIN=BIN
users/(default)/Toolbars/ModelVerse/saveModel.icon.png