Преглед на файлове

Even more (untested) code for the core algorithm

Yentl Van Tendeloo преди 8 години
родител
ревизия
2ceeb7f32f
променени са 3 файла, в които са добавени 468 реда и са изтрити 3 реда
  1. 213 3
      core/core_algorithm.alc
  2. 254 0
      core/mini_modify.alc
  3. 1 0
      core/mini_modify.alh

+ 213 - 3
core/core_algorithm.alc

@@ -66,8 +66,14 @@ Integer function get_relation_to_model(user_id : String, model_id : String):
 				// We are not related whatsoever
 				return 2!
 
-Boolean function allow_read(user_id : String, model_id : String):
+Boolean function is_admin(user_id : String):
 	if (read_attribute(core, user_id, "admin")):
+		return True!
+	else:
+		return False!
+	
+Boolean function allow_read(user_id : String, model_id : String):
+	if (is_admin(user_id)):
 		// Is admin, so always allow
 		return True!
 	else:
@@ -80,7 +86,7 @@ Boolean function allow_read(user_id : String, model_id : String):
 			return False!
 
 Boolean function allow_write(user_id : String, model_id : String):
-	if (read_attribute(core, user_id, "admin")):
+	if (is_admin(user_id)):
 		// Is admin, so always allow
 		return True!
 	else:
@@ -92,7 +98,21 @@ Boolean function allow_write(user_id : String, model_id : String):
 		else:
 			return False!
 
+Boolean function allow_change_metadata(user_id : String, model_id : String):
+	if (is_admin(user_id)):
+		// Is admin, so always allow
+		return True!
+	else:
+		if (get_relation_to_model(user_id, model_id) == "0"):
+			// Only owner can chmod
+			return True!
+		else:
+			return False!
+
 Void function user_function():
+	// Now the username is bound to the task ID, so there is no problem
+	// TODO check whether username isn't registered yet
+
 	// Add user to Core Formalism
 	String user_id
 	user_id = instantiate_node(core, "User", "")
@@ -105,13 +125,203 @@ Void function user_function():
 	// User destroyed already, so just stop execution
 	return !
 
+String function get_model_id(name : String):
+	Element models
+	String model
+
+	models = allInstances(core, "Model")
+	while (read_nr_out(models) > 0):
+		model = set_pop(models)
+		if (read_attribute(core, model, "name") == name):
+			return model!
+	
+	return ""!
+
 Void function user_function_skip_init(user_id : String)
 	Boolean do_continue
+	String cmd
 
 	do_continue = True
 
+	output("Welcome to the Model Management Interface v2.0!")
+	output("Use the 'help' command for a list of possible commands")
+
 	while (do_continue):
-		// TODO model management interface with access control restrictions
+		output("Ready for command...")
+		cmd = input()
+		if (cmd == "help"):
+			output("Model operations")
+			output("    model_add						-- Add a new model")
+			output("    model_modify					-- Modify an existing model")
+			output("    model_delete					-- [TODO] Delete a model and all related transformations")
+			output("    model_list						-- List all models")
+			output("    model_list_full					-- List all models with full info")
+			output("")
+			output("Transformation-specific operations")
+			output("    transformation_add				-- TODO")
+			output("    transformation_source_add		-- TODO")
+			output("    transformation_source_delete	-- TODO")
+			output("    transformation_target_add		-- TODO")
+			output("    transformation_target_delete	-- TODO")
+			output("    transformation_execute			-- TODO")
+			output("")
+			output("Model permission operations")
+			output("    permission_modify				-- TODO")
+			output("    permission_owner				-- TODO")
+			output("    permission_group				-- TODO")
+			output("")
+			output("Group operations")
+			output("    group_create					-- TODO")
+			output("    group_delete					-- TODO")
+			output("    group_owner						-- TODO")
+			output("    group_join						-- TODO")
+			output("    group_kick						-- TODO")
+			output("")
+			output("Admin operations")
+			output("    admin_promote					-- Promote a user to admin status")
+			output("    admin_demote					-- Demote a user to normal status")
+			output("")
+			output("General operations")
+			output("    account_delete					-- Remove current user and revoke all permissions ")
+
+		elif (cmd == "model_add"):
+			// Model addition operation, which uses model upload commands of the compiler
+			String name
+			String type
+			String location
+			Element new_model
+
+			output("Creating new model!")
+			output("Model type?")
+			type_id = get_model_id(input())
+			if (type_id != ""):
+				// Type exists
+				if (allow_read(user_id, type_id)):
+					// And is readable
+					output("Model name?")
+					name = input()
+					if (get_model_id(name) == ""):
+						// Model doesn't exist yet
+						output("Waiting for model constructors...")
+						// TODO update for access control
+						new_model = construct_model(read_attribute(core, type_id, "location"))
+						output("Model upload success!")
+						location = "/models/" + cast_id2s(new_model)
+						export_node(new_model, location)
+
+						// Manage meta-info
+						new_model_id = instantiate_node(core, "Model", "")
+						instantiate_attribute(core, new_model_id, "name", name)
+						instantiate_attribute(core, new_model_id, "location", location)
+						instantiate_attribute(core, new_model_id, "permissions", "300")
+						instantiate_link(core, "owner", "", new_model_id, user_id)
+						instantiate_link(core, "instanceOf", "", new_model_id, type_id)
+						output("Meta-info correctly set!")
+					else:
+						output("Model with that name already exists!")
+				else:
+					output("You are not allowed to read this type model!")
+			else:
+				output("Could not find type model!")
+
+		elif (cmd == "model_modify"):
+			// Model modify operation, which uses the mini_modify.alc operations, though with extensions for access control
+			String model_id
+
+			output("Which model do you want to modify?")
+			model_id = get_model_id(input())
+
+			if (model_id != ""):
+				if (allow_read(user_id, model_id)):
+					mini_modify(import_node(read_attribute(core, model_id, "location")), allow_write(user_id, model_id))
+				else:
+					output("You are not allowed to read this model!")
+			else:
+				output("Could not find model!")
+
+		elif (cmd == "model_delete"):
+			// Delete a model and all of its related transformations
+			String model_id
+
+			output("=================================================")
+			output("WARNING: Deletion is a very destructive operation")
+			output("         as it also deletes all transformations  ")
+			output("         defined which make use of this model!   ")
+			output("=================================================")
+
+			output("")
+			output("Currently not supported!")
+
+		elif (cmd == "model_list"):
+			// List all models
+			Element models
+			String m
+
+			models = allInstances(core, "Model")
+			while (read_nr_out(models) > 0):
+				m = set_pop(models)
+				output(("  " + (read_attribute(core, m, "name")) + " : ") + read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name"))
+
+		elif (cmd == "model_list_full")
+			// List all models with full info
+			Element models
+			String m
+			String permissions
+			String owner
+			String group
+			String name
+			String type
+
+			models = allInstances(core, "Model")
+			while (read_nr_out(models) > 0):
+				m = set_pop(models)
+				permissions = read_attribute(core, m, "permissions")
+				owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
+				group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
+				name = read_attribute(core, m, "name")
+				size = read_nr_out(dict_read(import_node(read_attribute(core, m, "location")), "model"))
+				type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")
+				output((((((((((("  " + permissions) + "  ") + owner) + " ") + group) + "    ") + size) + "   ") + name) + " : ") + type)
+
+		elif (cmd == "admin_promote"):
+			// Promote a user to admin status
+			if (is_admin(user_id)):
+				String other_user_id
+
+				output("Which user do you want to promote?")
+				other_user_id = get_user_id(input())
+				if (other_user_id != ""):
+					unset_attribute(core, other_user_id, "admin")
+					instantiate_attribute(core, other_user_id, "admin", True)
+					output("Permissions granted!")
+				else:
+					output("No such user!")
+			else:
+				output("Permission denied!")
+
+		elif (cmd == "admin_demote"):
+			// Demote a user to normal status
+			if (is_admin(user_id)):
+				String other_user_id
+
+				output("Which user do you want to demote?")
+				other_user_id = get_user_id(input())
+				if (other_user_id != ""):
+					unset_attribute(core, other_user_id, "admin")
+					instantiate_attribute(core, other_user_id, "admin", False)
+					output("Permissions revoked!")
+				else:
+					output("No such user!")
+			else:
+				output("Permission denied!")
+
+		elif (cmd == "exit"):
+			// Exit by actually removing the user and decoupling it from all of its models
+			// Restarting with the same user name will NOT grant you access to anything of the previous user with that same name
+			do_continue = False
 
 	// Delete user from Core Formalism
+	model_delete_element(core, user_id)
+	output("Goodbye!")
+
 	return !

+ 254 - 0
core/mini_modify.alc

@@ -0,0 +1,254 @@
+include "primitives.alh"
+include "constructors.alh"
+include "object_operations.alh"
+include "library.alh"
+include "conformance_scd.alh"
+include "io.alh"
+include "metamodels.alh"
+include "modelling.alh"
+include "compilation_manager.alh"
+
+Element function modify(model : Element, write : Boolean):
+	String cmd
+
+	Element attr_list_pn
+	Element attr_keys_pn
+	String attr_key_pn
+	Element metamodel_element_pn
+	String typename
+
+	output("Model loaded, ready for commands!")
+	output("Use 'help' command for a list of possible commands")
+
+	while (True):
+		output("Please give your command.")
+		cmd = input()
+		if (cmd == "help"):
+			output("Generic model operations:")
+			output("  instantiate -- Create a new model element")
+			output("  delete      -- Delete an existing element")
+			output("  attr_add    -- Add an attribute to an element")
+			output("  attr_del    -- Delete an attribute of an element")
+			output("  constrain   -- Add a constraint function to the model")
+			output("  rename      -- Rename an existing element")
+			output("  modify      -- Modify the attributes of an element")
+			output("  list        -- Prints the list of elements in the model")
+			output("  types       -- Prints the list of elements that can be instantiated")
+			output("  read        -- Prints the current state of a model element")
+			output("  verify      -- Check whether the model conforms to the metamodel")
+			output("  retype      -- Change the type of an element")
+			output("  exit        -- Leave the modification interface")
+		elif (cmd == "exit"):
+			return model!
+		elif (cmd == "instantiate"):
+			String mm_type_name
+			output("Type to instantiate?")
+			mm_type_name = input()
+			if (dict_in(model["metamodel"]["model"], mm_type_name)):
+				String element_name
+				output("Name of new element?")
+				element_name = input()
+				if (dict_in(model["model"], element_name)):
+					output("Element already exists; aborting")
+				else:
+					if (is_edge(model["metamodel"]["model"][mm_type_name])):
+						output("Source name?")
+						String src_name
+						src_name = input()
+						if (dict_in(model["model"], src_name)):
+							output("Destination name?")
+							String dst_name
+							dst_name = input()
+							if (dict_in(model["model"], dst_name)):
+								instantiate_link(model, mm_type_name, element_name, src_name, dst_name)
+								output("Instantiation successful!")
+							else:
+								output("Unknown destination; aborting")
+						else:
+							output("Unknown source; aborting")
+					else:
+						instantiate_node(model, mm_type_name, element_name)
+						output("Instantiation successful!")
+			else:
+				output("Unknown type specified; aborting")
+		elif (cmd == "set_inheritance"):
+			String inh_name
+
+			output("Which link in the metamodel is the inheritance link?")
+			inh_name = input()
+
+			if (dict_in(model["metamodel"]["model"], inh_name)):
+				dict_add(model, "inheritance", model["metamodel"]["model"][inh_name])
+				output("Set inheritance link!")
+			else:
+				output("Element not found in metamodel; aborting")
+
+		elif (cmd == "constrain"):
+			output("Element to constrain (empty for global)?")
+			String model_name
+			model_name = input()
+
+			if (model_name == ""):
+				// Global constraint
+				output("Give input to function constructors for GLOBAL constraint!")
+				set_model_constraints(model, construct_function())
+			elif (dict_in(model["model"], model_name)):
+				// Local constraint for this model
+				output("Give input to function constructors for LOCAL constraint!")
+				add_constraint(model, model_name, construct_function())
+				output("Added constraint to model!")
+			else:
+				// Local constraint, but model not found
+				output("Unknown model; aborting")
+		elif (cmd == "modify"):
+			String model_name
+			output("Element to modify?")
+			model_name = input()
+			if (dict_in(model["model"], model_name)):
+				Element attrs
+				attrs = getAttributeList(model, model_name)
+				String attr_name
+				output("Attribute to modify?")
+				attr_name = input()
+				if (set_in(dict_keys(attrs), attr_name)):
+					output("New value?")
+					unset_attribute(model, model_name, attr_name)
+					instantiate_attribute(model, model_name, attr_name, input())
+					output("Modified!")
+				else:
+					output("No such attribute!")
+			else:
+				output("No such model!")
+		elif (cmd == "attr_add"):
+			String model_name
+			output("Which model do you want to assign an attribute to?")
+			model_name = input()
+			if (dict_in(model["model"], model_name)):
+				Element attrs
+				attrs = getAttributeList(model, model_name)
+				String attr_name
+				output("Which attribute do you wish to assign?")
+				attr_name = input()
+				if (set_in(dict_keys(attrs), attr_name)):
+					output("Value of attribute?")
+					instantiate_attribute(model, model_name, attr_name, input())
+					output("Added attribute!")
+				else:
+					output("No such attribute!")
+			else:
+				output("No such model!")
+		elif (cmd == "attr_del"):
+			String model_name
+			output("Which model do you want to remove an attribute of?")
+			model_name = input()
+			if (dict_in(model["model"], model_name)):
+				Element attrs
+				attrs = getAttributeList(model, model_name)
+				String attr_name
+				output("Which attribute do you want to delete?")
+				attr_name = input()
+				if (set_in(dict_keys(attrs), attr_name)):
+					unset_attribute(model, model_name, attr_name)
+					output("Attribute deleted!")
+				else:
+					output("No such attribute!")
+			else:
+				output("No such model!")
+		elif (cmd == "delete"):
+			output("What is the name of the element you want to delete?")
+			cmd = input()
+			if (dict_in(model["model"], cmd)):
+				model_delete_element(model, cmd)
+				output("Deleted!")
+			else:
+				output("No such element; aborting")
+		elif (cmd == "rename"):
+			output("Old name?")
+			String old_name_e
+			old_name_e = input()
+			if (dict_in(model["model"], old_name_e)):
+				output("New name?")
+				String new_name_e
+				new_name_e = input()
+				if (dict_in(model["model"], new_name_e)):
+					output("New name already used; aborting")
+				else:
+					dict_add(model["model"], new_name_e, model["model"][old_name_e])
+					dict_delete(model["model"], old_name_e)
+					output("Rename complete!")
+			else:
+				output("Unknown element; aborting")
+		elif (cmd == "list"):
+			Element keys_m
+			keys_m = dict_keys(model["model"])
+			output("List of all elements:")
+			String v_m
+			while (read_nr_out(keys_m) > 0):
+				v_m = set_pop(keys_m)
+				// Filter out anonymous objects
+				if (bool_not(string_startswith(v_m, "__"))):
+					typename = reverseKeyLookup(model["metamodel"]["model"], dict_read_node(model["type_mapping"], model["model"][v_m]))
+					output((("  " + v_m) + " : ") + typename)
+		elif (cmd == "read"):
+			output("Element to read?")
+			cmd = input()
+			if (dict_in(model["model"], cmd)):
+				Element read_elem
+				read_elem = model["model"][cmd]
+				metamodel_element_pn = dict_read_node(model["type_mapping"], read_elem)
+
+				output("Name: " + cmd)
+				output("Type: " + reverseKeyLookup(model["metamodel"]["model"], metamodel_element_pn))
+				if (is_edge(read_elem)):
+					output("Source: " + reverseKeyLookup(model["model"], read_edge_src(read_elem)))
+					output("Destination: " + reverseKeyLookup(model["model"], read_edge_dst(read_elem)))
+				if (cast_v2s(read_elem) != "None"):
+					output("Value: " + cast_v2s(read_elem))
+				output("Defines attributes:")
+				attr_list_pn = getInstantiatableAttributes(model, read_elem)
+				attr_keys_pn = dict_keys(attr_list_pn)
+				while (0 < read_nr_out(attr_keys_pn)):
+					attr_key_pn = set_pop(attr_keys_pn)
+					output(((("  " + attr_key_pn) + " : ") + cast_v2s(attr_list_pn[attr_key_pn])))
+				output("Attributes:")
+				attr_list_pn = getAttributeList(model, cmd)
+				attr_keys_pn = dict_keys(attr_list_pn)
+				while (0 < read_nr_out(attr_keys_pn)):
+					attr_key_pn = set_pop(attr_keys_pn)
+					output((((("  " + cast_v2s(attr_key_pn)) + " : ") + cast_v2s(attr_list_pn[attr_key_pn])) + " = ") + cast_v2s(read_attribute(model, reverseKeyLookup(model["model"], read_elem), attr_key_pn)))
+			else:
+				output("Unknown element; aborting")
+		elif (cmd == "verify"):
+			output(conformance_scd(model))
+		elif (cmd == "types"):
+			Element keys_t
+			keys_t = dict_keys(model["metamodel"]["model"])
+			output("List of types:")
+			String v_t
+			while (read_nr_out(keys_t) > 0):
+				v_t = set_pop(keys_t)
+				if (bool_not(string_startswith(v_t, "__"))):
+					output(string_join(("  " + v_t) + " : ", reverseKeyLookup(model["metamodel"]["metamodel"]["model"], dict_read_node(model["metamodel"]["type_mapping"], model["metamodel"]["model"][v_t]))))
+		elif (cmd == "retype"):
+			output("Element to retype?")
+			String elementname
+			elementname = input()
+			if (dict_in(model["model"], elementname)):
+				output("New type")
+				typename = input()
+				if (dict_in(model["metamodel"]["model"], typename)):
+					// OK, do the retyping
+					// First try removing the previous type if it exists
+					dict_delete_node(model["type_mapping"], model["model"][elementname])
+					// Now add the new type
+					dict_add(model["type_mapping"], model["model"][elementname], model["metamodel"]["model"][typename])
+					output("Retyped!")
+				else:
+					output("Unknown type; aborting")
+			else:
+				output("Unknown element; aborting")
+		else:
+			output("Unknown command: " + cast_v2s(cmd))
+			output("Use command 'help' to get a list of available commands")
+
+	return model!

+ 1 - 0
core/mini_modify.alh

@@ -0,0 +1 @@
+Element function modify(model : Element, write : Boolean)