include "modelling.alh" include "library.alh" include "primitives.alh" include "constructors.alh" include "object_operations.alh" include "mini_modify.alh" include "model_management.alh" include "ramify.alh" include "conformance_scd.alh" include "transform.alh" include "metamodels.alh" Element core = ? String admin_username = "admin" String admin_password = "admin" String core_location = "models/CoreFormalism" String core_model_location = "core" String function JSON_print(model : Element): String result Element keys_m String v_m String type String attr_key Element attr_keys Boolean first Element attr_value result = "[" keys_m = dict_keys(model["model"]) first = True while (read_nr_out(keys_m) > 0): v_m = set_pop(keys_m) type = read_type(model["metamodel"], read_type(model, v_m)) if (bool_or(type == "Class", type == "Association")): if (bool_not(first)): result = result + "," else: first = False result = result + "{" result = (((result + "\"id\": \"") + v_m) + "\"") result = (((result + ",") + "\"type\": \"") + read_type(model, v_m)) + "\"" if (type == "Association"): result = (((result + ", \"__source\": \"") + reverseKeyLookup(model["model"], read_edge_src(model["model"][v_m]))) + "\"") result = (((result + ", \"__target\": \"") + reverseKeyLookup(model["model"], read_edge_dst(model["model"][v_m]))) + "\"") // Has attributes attr_keys = dict_keys(getAttributeList(model, v_m)) while (0 < read_nr_out(attr_keys)): attr_key = set_pop(attr_keys) attr_value = read_attribute(model, v_m, attr_key) if (element_eq(attr_value, read_root())): result = (((result + ", \"") + attr_key) + "\": null") else: if (is_physical_boolean(attr_value)): if (attr_value): result = ((result + ", \"") + attr_key) + "\": true" else: result = ((result + ", \"") + attr_key) + "\": false" else: result = ((((result + ", \"") + attr_key) + "\": ") + cast_v2s(attr_value)) result = result + "}" result = result + "]" return result! Void function initialize_core(): // Initialize the Core Formalism String core_model String core_formalism_model String scd_model Element al_model String admin_group String admin_user String nobody_group String instance_of String core_formalism Element scd Element al Element pm Element tracability Element conformance String pm_model String tracability_model String coreM_model_location String pm_location String scd_location String al_location String tracability_location String conformance_location coreM_model_location = "models/core" pm_location = "models/ProcessModel" scd_location = "models/SimpleClassDiagrams" al_location = "models/ActionLanguage" tracability_location = "models/Tracability" conformance_location = "models/Conformance_MV" // Annotate action language fragments //TODO Uncomment, but takes some time... //add_code_model(import_node(al_location), conformance_location, wrap_conformance) scd = import_node(scd_location) al = import_node(al_location) pm = import_node(pm_location) tracability = import_node(tracability_location) conformance = import_node(conformance_location) // Create the Model itself and make public core_formalism = import_node(core_location) core = instantiate_model(core_formalism) export_node(core_model_location, core) export_node(coreM_model_location, core["model"]) // Create admin group admin_group = instantiate_node(core, "Group", "") instantiate_attribute(core, admin_group, "name", "admin") // Create nobody group nobody_group = instantiate_node(core, "Group", "") instantiate_attribute(core, nobody_group, "name", "nobody") // Create admin user admin_user = instantiate_node(core, "User", "") instantiate_attribute(core, admin_user, "name", admin_username) instantiate_attribute(core, admin_user, "admin", True) instantiate_attribute(core, admin_user, "password", hash(admin_password)) // Create link between admin user and group instantiate_link(core, "ownedBy", "", admin_group, admin_user) instantiate_link(core, "belongsTo", "", admin_user, admin_group) // Add the SimpleClassDiagrams formalism already scd_model = instantiate_node(core, "Model", "") instantiate_attribute(core, scd_model, "name", "SimpleClassDiagrams") instantiate_attribute(core, scd_model, "location", scd_location + "/model") instantiate_attribute(core, scd_model, "permissions", "221") instance_of = instantiate_link(core, "instanceOf", "", scd_model, scd_model) instantiate_attribute(core, instance_of, "type_mapping", scd["type_mapping"]) instantiate_link(core, "group", "", scd_model, admin_group) instantiate_link(core, "owner", "", scd_model, admin_user) // Add the Tracability formalism tracability_model = instantiate_node(core, "Model", "") instantiate_attribute(core, tracability_model, "name", "Tracability") instantiate_attribute(core, tracability_model, "location", tracability_location + "/model") instantiate_attribute(core, tracability_model, "permissions", "221") instance_of = instantiate_link(core, "instanceOf", "", tracability_model, scd_model) instantiate_attribute(core, instance_of, "type_mapping", tracability["type_mapping"]) instantiate_link(core, "group", "", tracability_model, admin_group) instantiate_link(core, "owner", "", tracability_model, admin_user) // Add the Process Model formalism pm_model = instantiate_node(core, "Model", "") instantiate_attribute(core, pm_model, "name", "ProcessModel") instantiate_attribute(core, pm_model, "location", pm_location + "/model") instantiate_attribute(core, pm_model, "permissions", "221") instance_of = instantiate_link(core, "instanceOf", "", pm_model, scd_model) instantiate_attribute(core, instance_of, "type_mapping", pm["type_mapping"]) instantiate_link(core, "group", "", pm_model, admin_group) instantiate_link(core, "owner", "", pm_model, admin_user) // Add the Action Language formalism al_model = instantiate_node(core, "Model", "") instantiate_attribute(core, al_model, "name", "ActionLanguage") instantiate_attribute(core, al_model, "location", al_location + "/model") instantiate_attribute(core, al_model, "permissions", "221") instance_of = instantiate_link(core, "instanceOf", "", al_model, scd_model) instantiate_attribute(core, instance_of, "type_mapping", al["type_mapping"]) instantiate_link(core, "group", "", al_model, admin_group) instantiate_link(core, "owner", "", al_model, admin_user) // Add the Manual Operation formalism Element manual String manual_model manual = instantiate_model(scd) manual_model = instantiate_node(core, "Model", "") export_node("models/ManualOperation", manual) instantiate_attribute(core, manual_model, "name", "ManualOperation") instantiate_attribute(core, manual_model, "location", "models/ManualOperation/model") instantiate_attribute(core, manual_model, "permissions", "221") instance_of = instantiate_link(core, "instanceOf", "", manual_model, scd_model) instantiate_attribute(core, instance_of, "type_mapping", create_node()) instantiate_link(core, "group", "", manual_model, admin_group) instantiate_link(core, "owner", "", manual_model, admin_user) // Add the conformance operation as action language String conf conf = instantiate_node(core, "ActionLanguage", "") instantiate_attribute(core, conf, "name", "conformance_mv") instantiate_attribute(core, conf, "location", conformance_location + "/model") instantiate_attribute(core, conf, "permissions", "221") instance_of = instantiate_link(core, "instanceOf", "", conf, al_model) instantiate_attribute(core, instance_of, "type_mapping", conformance["type_mapping"]) instantiate_link(core, "group", "", conf, admin_group) instantiate_link(core, "owner", "", conf, admin_user) String lnk lnk = instantiate_link(core, "transformInput", "", conf, scd_model) instantiate_attribute(core, lnk, "name", "metamodel") lnk = instantiate_link(core, "transformInput", "", conf, scd_model) instantiate_attribute(core, lnk, "name", "model") // Add the core formalism already core_formalism_model = instantiate_node(core, "Model", "") instantiate_attribute(core, core_formalism_model, "name", "CoreFormalism") instantiate_attribute(core, core_formalism_model, "location", core_location + "/model") instantiate_attribute(core, core_formalism_model, "permissions", "221") instance_of = instantiate_link(core, "instanceOf", "", core_formalism_model, scd_model) instantiate_attribute(core, instance_of, "type_mapping", core_formalism["type_mapping"]) instantiate_link(core, "group", "", core_formalism_model, admin_group) instantiate_link(core, "owner", "", core_formalism_model, admin_user) // Add the core model core_model = instantiate_node(core, "Model", "") instantiate_attribute(core, core_model, "name", "core") instantiate_attribute(core, core_model, "location", coreM_model_location) instantiate_attribute(core, core_model, "permissions", "200") instance_of = instantiate_link(core, "instanceOf", "", core_model, core_formalism_model) instantiate_attribute(core, instance_of, "type_mapping", core["type_mapping"]) instantiate_link(core, "group", "", core_model, admin_group) instantiate_link(core, "owner", "", core_model, admin_user) // Call this for ourselves as well //log("MvC is ready!") return ! String function get_instanceOf_link(model_id : String): Element all_links String choice all_links = allOutgoingAssociationInstances(core, model_id, "instanceOf") if (read_nr_out(all_links) > 1): log("WARNING: multiple instanceOf relations were detected for this model; picking one at random!") elif (read_nr_out(all_links) == 0): log("ERROR: untyped model!") choice = set_pop(allOutgoingAssociationInstances(core, model_id, "instanceOf")) return choice! Element function get_full_model(model_id : String): Element m Element all_links String choice choice = get_instanceOf_link(model_id) m = create_node() dict_add(m, "model", import_node(read_attribute(core, model_id, "location"))) dict_add(m, "type_mapping", read_attribute(core, choice, "type_mapping")) if (readAssociationDestination(core, choice) == model_id): // Found the meta-circular level, so we can stop! dict_add(m, "metamodel", m) else: dict_add(m, "metamodel", get_full_model(readAssociationDestination(core, choice))) return m! Integer function get_relation_to_model(user_id : String, model_id : String): if (set_in(allAssociationDestinations(core, model_id, "owner"), user_id)): // We are the owner return 0! else: String group_id group_id = set_pop(allAssociationDestinations(core, model_id, "group")) if (set_in(allAssociationDestinations(core, user_id, "belongsTo"), group_id)): // We are in the owning group return 1! else: // We are not related whatsoever return 2! 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: // Check permissions String permission permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id)) if (bool_or(permission == "1", permission == "2")): return True! else: return False! Boolean function allow_write(user_id : String, model_id : String): if (is_admin(user_id)): // Is admin, so always allow return True! else: // Check permissions String permission permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id)) if (permission == "2"): return True! 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! Boolean function allow_group_modify(user_id : String, group_id : String): if (is_admin(user_id)): // Is admin, so always allow return True! else: if (read_nr_out(set_overlap(allIncomingAssociationInstances(core, user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))) > 0): // We are an owner return True! else: return False! Boolean function check_login(user_id : String): String password String stored_password stored_password = read_attribute(core, user_id, "password") output("Password for existing user?") password = hash(input()) return password == stored_password! Element function extract_ftg(user_id : String): // Extract your personal FTG, showing only the readable models that can be opened // This function does the actual projection of transformations // TODO: Only keep transformations satisfying some properties! return create_node()! Void function new_task(): String username String user_id String password // Load in a hard-reference to the previously created model core = import_node(core_model_location) while (True): output("Log on as which user?") username = input() user_id = get_user_id(username) if (user_id == ""): // New user // Add user to Core Formalism user_id = instantiate_node(core, "User", "") instantiate_attribute(core, user_id, "name", username) instantiate_attribute(core, user_id, "admin", False) output("This is a new user: please give password!") password = hash(input()) output("Please repeat the password") if (password == hash(input())): output("Passwords match!") instantiate_attribute(core, user_id, "password", password) break! else: output("Not the same password!") else: if (check_login(user_id)): break! else: output("Wrong password!") user_function_skip_init(user_id) // 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 (value_eq(name, read_attribute(core, model, "name"))): return model! return ""! String function get_user_id(name : String): Element users String user users = allInstances(core, "User") while (read_nr_out(users) > 0): user = set_pop(users) if (value_eq(read_attribute(core, user, "name"), name)): return user! return ""! String function get_group_id(name : String): Element groups String group groups = allInstances(core, "Group") while (read_nr_out(groups) > 0): group = set_pop(groups) if (value_eq(read_attribute(core, group, "name"), name)): return group! return ""! Void function model_create(model : Element, name : String, user_id : String, type_id : String, kind : String): String location String model_id String instance_of location = "models/" + cast_id2s(model) export_node(location, model["model"]) // Manage meta-info model_id = instantiate_node(core, kind, "") instantiate_attribute(core, model_id, "name", name) instantiate_attribute(core, model_id, "location", location) instantiate_attribute(core, model_id, "permissions", "200") instantiate_link(core, "owner", "", model_id, user_id) instantiate_link(core, "group", "", model_id, get_group_id("nobody")) instance_of = instantiate_link(core, "instanceOf", "", model_id, type_id) instantiate_attribute(core, instance_of, "type_mapping", model["type_mapping"]) return! Void function model_overwrite(model : Element, model_id : String): String location String instanceOf_link location = "models/" + cast_id2s(model) export_node(location, model["model"]) // Change location in meta-data unset_attribute(core, model_id, "location") instantiate_attribute(core, model_id, "location", location) instanceOf_link = get_instanceOf_link(model_id) unset_attribute(core, instanceOf_link, "type_mapping") instantiate_attribute(core, instanceOf_link, "type_mapping", model["type_mapping"]) return! Boolean function check_is_typed_by(model_id : String, metamodel_id : String): // TODO check if there is actually an instanceOf link between them // --> quick check! return True! Boolean function check_conformance(model_id : String): // TODO check if it actually conforms, considering that instanceOf link // --> in-depth check return True! Boolean function pm_finished(worklist : Element, pm : String): Element finished Integer cnt Integer i // Check if any of the "finish" elements are in the worklist // If so, we can already finish, and therefore will stop immediately finished = allInstances(pm, "Finish") i = 0 cnt = read_nr_out(finished) while (i < cnt): // Check each finished element individually if (set_in(finished, dict_read(read_edge_dst(read_out(worklist, i)), 0))): return True! i = i + 1 return False! Element function execute_operation(operation_id : String, input_models : Element, output_models : Element, tracability_model : Element): // Operations are always in-place and uses only a single metamodel // Therefore, we must: // 1) Find merged metamodel // 2) Merge the different source models and retype // 3) Perform the operation on the merged model // 4) Split the resulting model based on the target formalisms; if operation successful Element input_model String trace_link_id Element merged_model String merged_metamodel_id String ramified_metamodel_id Boolean result String exact_type Element trace_links String linktype String model_ID String key Element keys Element input_keys Element output_keys Element model_tuples String metamodel_name Element metamodel String metamodel_ID Boolean tracability // 1) Find merged metamodel exact_type = read_type(core, operation_id) if (exact_type == "ModelTransformation"): linktype = "RAMified" ramified_metamodel_id = set_pop(allAssociationDestinations(core, operation_id, "instanceOf")) trace_links = allOutgoingAssociationInstances(core, ramified_metamodel_id, "tracability") elif (exact_type == "ManualOperation"): linktype = "operatesOn" trace_links = allOutgoingAssociationInstances(core, operation_id, "tracability") elif (exact_type == "ActionLanguage"): linktype = "operatesOn" trace_links = allOutgoingAssociationInstances(core, operation_id, "tracability") else: // Don't know how to execute this operation! return read_root()! merged_metamodel_id = "" while (read_nr_out(trace_links) > 0): trace_link_id = set_pop(trace_links) if (value_eq(read_attribute(core, trace_link_id, "type"), linktype)): merged_metamodel_id = readAssociationDestination(core, trace_link_id) if (merged_metamodel_id != ""): // 2) Merge source models model_tuples = create_node() keys = dict_keys(input_models) while (read_nr_out(keys) > 0): key = set_pop(keys) set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(input_models[key])))) merged_model = model_join(model_tuples, get_full_model(merged_metamodel_id), tracability_model) // 3) Transform if (exact_type == "ModelTransformation"): result = transform(merged_model, get_full_model(operation_id)) elif (exact_type == "ManualOperation"): output("Please perform manual operation " + cast_v2s(read_attribute(core, operation_id, "name"))) modify(merged_model, True) result = True elif (exact_type == "ActionLanguage"): Element func func = get_func_AL_model(get_full_model(operation_id)) result = func(merged_model) else: log("ERROR") // 4) Split in different models depending on type if (element_neq(tracability_model, read_root())): tracability = True else: tracability = False if (result): model_tuples = create_node() keys = dict_keys(output_models) while (read_nr_out(keys) > 0): key = set_pop(keys) set_add(model_tuples, create_tuple(key, get_full_model(get_model_id(output_models[key])))) result = model_split(merged_model, model_tuples, tracability) if (tracability): Element new_tracability_model new_tracability_model = result["__tracability"] dict_overwrite(tracability_model, "model", new_tracability_model["model"]) dict_overwrite(tracability_model, "type_mapping", new_tracability_model["type_mapping"]) dict_overwrite(tracability_model, "metamodel", new_tracability_model["metamodel"]) dict_delete(result, "__tracability") return result! else: return read_root()! else: output("Could not resolve intermediate merged metamodel") return read_root()! Boolean function enact_action(pm : Element, element : String, prefix : String, user_id : String): Boolean result String transformation_id Element lst String elem Element inputs Element outputs String type_name String exact_type Element trace_links Element output_mms Element consumes_link String name String value String elem_name Element keys String key String consume String produce Element output_map inputs = create_node() outputs = create_node() output_map = create_node() // Read out the referenced element from the MvC transformation_id = get_model_id(read_attribute(pm, element, "name")) // Find all input model names lst = allOutgoingAssociationInstances(pm, element, "Consumes") while (read_nr_out(lst) > 0): consume = set_pop(lst) value = read_attribute(pm, readAssociationDestination(pm, consume), "name") dict_add(inputs, read_attribute(pm, consume, "name"), prefix + value) // Find all output model names and their metamodel lst = allOutgoingAssociationInstances(pm, element, "Produces") while (read_nr_out(lst) > 0): produce = set_pop(lst) elem = readAssociationDestination(pm, produce) type_name = read_attribute(pm, elem, "type") elem_name = read_attribute(pm, elem, "name") dict_add(outputs, read_attribute(pm, produce, "name"), type_name) dict_add(output_map, read_attribute(pm, produce, "name"), prefix + elem_name) if read_type(core, transformation_id) == "ActionLanguage": log(string_join("Enacting ActionLanguage: ", read_attribute(pm, element, "name"))) output(string_join("Enacting ActionLanguage: ", read_attribute(pm, element, "name"))) elif read_type(core, transformation_id) == "ManualOperation": log(string_join("Enacting ManualOperation: ", read_attribute(pm, element, "name"))) output(string_join("Enacting ManualOperation: ", read_attribute(pm, element, "name"))) else: log(string_join("Enacting ModelTransformation: ", read_attribute(pm, element, "name"))) output(string_join("Enacting ModelTransformation: ", read_attribute(pm, element, "name"))) result = execute_operation(transformation_id, inputs, outputs, read_root()) if (element_eq(result, read_root())): // Something went wrong! return False! else: keys = dict_keys(result) while (read_nr_out(keys) > 0): key = set_pop(keys) if (get_model_id(output_map[key]) == ""): // New model model_create(result[key], output_map[key], user_id, get_model_id(key), "Model") else: model_overwrite(result[key], get_model_id(output_map[key])) return True! Void function enact_PM(pm : Element, prefix : String, user_id : String): Element worklist String element String start String type Boolean result Element tuple Element counters Element join_nodes output("Success") // Initialize Join counters counters = create_node() join_nodes = allInstances(pm, "Join") while (read_nr_out(join_nodes) > 0): dict_add(counters, set_pop(join_nodes), 0) // Create the worklist with the Start instance as first element worklist = create_node() set_add(worklist, create_tuple(set_pop(allInstances(pm, "Start")), True)) while (bool_not(pm_finished(worklist, pm))): // Pop a random element from the list and execute it tuple = set_pop(worklist) element = tuple[0] result = tuple[1] // Find the type (to see what to do with it) // this does not yet yield the type of transformation, if it is an Execution type = read_type(pm, element) if (type == "Start"): // Initial node, just progress to the next elements // Nothing to do here though, as we have just started result = True elif (type == "Finish"): // Should be impossible, as we would have ended... result = result elif (type == "Fork"): result = result elif (type == "Join"): // Only do this if all dependencies are fullfilled // So add to the counter of this Join dict_overwrite(counters, element, integer_addition(counters[element], 1)) // Now check whether we have enough tokens to execute the Join itself Integer required Integer got required = read_nr_out(allIncomingAssociationInstances(pm, element, "Next")) + read_nr_out(allIncomingAssociationInstances(pm, element, "Else")) got = counters[element] if (got == required): // Reset counter to 0 dict_overwrite(counters, element, 0) // And continue else: // We haven't gotten all yet, so we wait (i.e., continue without adding Next link to worklist) continue! elif (type == "Exec"): // Execute a transformation // This the difficult part! result = enact_action(pm, element, prefix, user_id) elif (type == "Decision"): // If the previous result is true, we add the normal one, otherwise the false one // in this context, that means that if it is false, we should add it manually to the list, and then continue the simulation loop if (bool_not(result)): // Apparently it is False, so map this to the "Else" branch set_add(worklist, create_tuple(set_pop(allAssociationDestinations(pm, element, "Else")), True)) continue! else: // Apparently it is True, so map this to the "Then" branch set_add(worklist, create_tuple(set_pop(allAssociationDestinations(pm, element, "Then")), True)) continue! // We have finished the execution, so add all outgoing edges to the worklist Element all_next all_next = allAssociationDestinations(pm, element, "Next") String next while (read_nr_out(all_next) > 0): next = set_pop(all_next) set_add(worklist, create_tuple(next, result)) // Reached a finish element, so stop output("Success") return ! String function cmd_help(user_id : String): String result result = "" result = result + ("Model operations\n") result = result + (" model_add -- Add a new model\n") result = result + (" model_modify -- Modify an existing model\n") result = result + (" model_list -- List all models\n") result = result + (" model_list_full -- List all models with full info\n") result = result + (" model_overwrite -- Overwrites a model with an uploaded model, leaving all metadata\n") result = result + (" model_render -- Render a given model with a specified mapper\n") result = result + (" verify -- Check whether a model conforms to its metamodel\n") result = result + ("\n") result = result + ("Transformation-specific operations\n") result = result + (" transformation_add_MT -- Initialize a new model transformation\n") result = result + (" transformation_add_AL -- Initialize a new action language transformation\n") result = result + (" transformation_add_MANUAL -- Initialize a new manual transformation\n") result = result + (" transformation_execute -- Execute a transformation on a set of input models\n") result = result + (" transformation_list -- List all model transformations\n") result = result + (" transformation_list_full -- List all model transformations with permissions\n") result = result + (" transformation_detail -- List transformation details\n") result = result + (" transformation_between -- List all transformations between two metamodels\n") result = result + ("\n") result = result + ("Process operations\n") result = result + (" process_execute -- Execute a process model\n") result = result + ("\n") result = result + ("Model permission operations\n") result = result + (" permission_modify -- Change model permissions\n") result = result + (" permission_owner -- Change model owner\n") result = result + (" permission_group -- Change model group\n") result = result + ("\n") result = result + ("Group operations\n") result = result + (" group_create -- Create a group\n") result = result + (" group_delete -- Delete a group\n") result = result + (" group_owner_add -- Add group owner\n") result = result + (" group_owner_delete -- Remove group owner\n") result = result + (" group_join -- Add someone to your group\n") result = result + (" group_kick -- Kick someone from your group\n") result = result + (" group_list -- List all groups you are a member of\n") result = result + ("\n") if (is_admin(user_id)): result = result + ("Admin operations\n") result = result + (" admin_promote -- Promote a user to admin status\n") result = result + (" admin_demote -- Demote a user to normal status\n") result = result + ("\n") result = result + ("General operations\n") result = result + (" self-destruct -- Remove current user and revoke all permissions \n") result = result + (" exit -- Kill the current task, while retaining user\n") return result! String function cmd_model_add(user_id : String, type : String, name : String): // Model addition operation, which uses model upload commands of the compiler String location String type_id Element new_model String new_model_id type_id = get_model_id(type) if (type_id != ""): // Type exists if (allow_read(user_id, type_id)): // And is readable if (get_model_id(name) == ""): // Model doesn't exist yet output("Waiting for model constructors...") new_model = construct_model_raw(get_full_model(type_id)) model_create(new_model, name, user_id, type_id, "Model") return "Success"! else: return "Model exists: " + name! else: return "Permission denied to model: " + type! else: return "Model not found: " + type! String function cmd_process_execute(user_id : String, process : String, prefix : String): // Execute a process model until it reaches termination String process_id process_id = get_model_id(process) if (process_id != ""): if (allow_read(user_id, process_id)): enact_PM(get_full_model(process_id), prefix, user_id) return "Success"! else: return "Permission denied to model: " + process! else: return "Model not found: " + process! String function cmd_transformation_between(user_id : String, source_name : String, target_name : String): String source_id String target_id Element onSource Element onTarget Element result String transformation source_id = get_model_id(source_name) if (source_id != ""): target_id = get_model_id(target_name) if (target_id != ""): onSource = allAssociationOrigins(core, source_id, "transformInput") onTarget = allAssociationOrigins(core, target_id, "transformOutput") result = set_overlap(onSource, onTarget) String r r = "Success: " while (read_nr_out(result) > 0): transformation = set_pop(result) if (allow_read(user_id, transformation)): r = r + string_join(read_attribute(core, transformation, "name"), "\n") return r! else: return "Model not found: " + target_name! else: return "Model not found: " + source_name! String function cmd_model_render(user_id : String, model_name : String, mapper_name : String): String model_ID String mapper_ID String rendered_name String tracability_name String type_ID Element inputs Element outputs Element rendered_model Element tracability_model Element result Element out_links Element in_links model_ID = get_model_id(model_name) if (model_ID != ""): mapper_ID = get_model_id(mapper_name) if (allow_read(user_id, model_ID)): if (mapper_ID != ""): if (allow_read(user_id, mapper_ID)): // Everything is fine; start the actual operation // Find metamodel to render to rendered_name = (("__RENDERED_" + model_name) + "__") + mapper_name tracability_name = (("__TRACABILITY_" + model_name) + "__") + mapper_name // Take the abstract syntax model and the previously rendered model inputs = create_node() dict_add(inputs, "abstract", model_name) dict_add(inputs, "rendered", rendered_name) // Generate a new rendered model only (no write to original model!) outputs = create_node() out_links = allAssociationDestinations(core, mapper_ID, "transformOutput") in_links = allAssociationDestinations(core, mapper_ID, "transformInput") while(read_nr_out(out_links) > 0): type_ID = set_pop(out_links) if (bool_not(set_in(in_links, type_ID))): // It is not the AS model, but another one (the MM_rendered) break! // Add the model itself as output as well, as otherwise tracability links get messed up! dict_add(outputs, "abstract", read_attribute(core, set_pop(allAssociationDestinations(core, get_model_id(model_name), "instanceOf")), "name")) dict_add(outputs, "rendered", read_attribute(core, type_ID, "name")) // Rendered model doesn't exist yet, so create first if (get_model_id(rendered_name) == ""): // Rendered model doesn't exist yet, so create first! rendered_model = instantiate_model(get_full_model(type_ID)) model_create(rendered_model, rendered_name, user_id, type_ID, "Model") // Tracability model won't exist either tracability_model = instantiate_model(get_full_model(get_model_id("Tracability"))) model_create(tracability_model, tracability_name, user_id, get_model_id("Tracability"), "Model") else: // Read out tracability model tracability_model = get_full_model(get_model_id(tracability_name)) // Do the operation itself! result = execute_operation(mapper_ID, inputs, outputs, tracability_model) // Overwrite the previous rendered model model_overwrite(result[read_attribute(core, type_ID, "name")], get_model_id(rendered_name)) // Tracability updated in-place model_overwrite(tracability_model, get_model_id(tracability_name)) tracability_model = get_full_model(get_model_id(tracability_name)) // Also output the resulting model return "Success: " + JSON_print(get_full_model(get_model_id(rendered_name)))! else: return "Permission denied to model: " + mapper_name! else: return "Model not found: " + mapper_name! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_transformation_execute(user_id : String, transformation_name : String, source_models : Element, target_models : Element): // Execute a transformation, whatever type it is // First we detect the type, so we know how to prepare for invocation String transformation_id String exact_type Element sources Element targets String source String target Element inputs Element outputs Element output_map Element trace_links String target_model_name String source_model_name String source_model_ID Element result Element keys String key String assoc_name transformation_id = get_model_id(transformation_name) if (transformation_id != ""): if (allow_read(user_id, transformation_id)): if (is_nominal_instance(core, transformation_id, "Transformation")): // Read out source and target links inputs = create_node() sources = allOutgoingAssociationInstances(core, transformation_id, "transformInput") while (read_nr_out(sources) > 0): source = set_pop(sources) assoc_name = read_attribute(core, source, "name") if (dict_in(source_models, assoc_name)): source_model_name = source_models[assoc_name] else: return "Source model not bound: " + assoc_name! source_model_ID = get_model_id(source_model_name) if (source_model_ID != ""): if (allow_read(user_id, source_model_ID)): // Check for conformance to the requested metamodel if (check_is_typed_by(source_model_ID, source)): if (check_conformance(source_model_ID)): dict_add(inputs, assoc_name, source_model_name) continue! else: return "Incorrectly typed model: " + source_model_name! else: return "Incorrectly typed model: " + source_model_name! else: return "Permission denied to model: " + source_model_name! else: return "Model not found: " + source_model_name! targets = allOutgoingAssociationInstances(core, transformation_id, "transformOutput") outputs = create_node() output_map = create_node() while (read_nr_out(targets) > 0): target = set_pop(targets) assoc_name = read_attribute(core, target, "name") if (dict_in(target_models, assoc_name)): target_model_name = target_models[assoc_name] else: return "Target model not bound: " + assoc_name! if (get_model_id(target_model_name) == ""): // Doesn't exist yet, so we can easily create dict_add(output_map, assoc_name, read_attribute(core, readAssociationDestination(core, target), "name")) dict_add(outputs, assoc_name, target_model_name) else: // Already exists, so we need to check for write access if (allow_write(user_id, get_model_id(target_model_name))): dict_add(output_map, assoc_name, read_attribute(core, readAssociationDestination(core, target), "name")) dict_add(outputs, assoc_name, target_model_name) else: return "Permission denied to model: " + target_model_name! if (read_type(core, transformation_id) == "ActionLanguage"): output("Success: ready for AL execution") elif (read_type(core, transformation_id) == "ManualOperation"): output("Success: ready for MANUAL execution") else: output("Success: ready for MT execution") result = execute_operation(transformation_id, inputs, output_map, read_root()) // Now write out the models again if (element_eq(result, read_root())): // Something went wrong! return "Failure"! else: keys = dict_keys(result) while (read_nr_out(keys) > 0): key = set_pop(keys) if (get_model_id(outputs[key]) == ""): // New model model_create(result[key], outputs[key], user_id, get_model_id(key), "Model") else: model_overwrite(result[key], get_model_id(outputs[key])) return "Success"! else: return "Model is not executable: " + transformation_name! else: return "Permission denied to model: " + transformation_name! else: return "Model not found: " + transformation_name! String function cmd_verify(user_id : String, model_name : String): // Check whether a model conforms to its specification (with the selected type mapping) String model_id String result model_id = get_model_id(model_name) if (model_id != ""): if (allow_read(user_id, model_id)): result = conformance_scd(get_full_model(model_id)) return "Success: " + result! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_model_overwrite(user_id : String, model_name : String): // Overwrites an existing model without changing any metadata String model_id String type_id Element new_model model_id = get_model_id(model_name) if (model_id != ""): if (allow_write(user_id, model_id)): type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf")) if (allow_read(user_id, type_id)): output("Waiting for model constructors...") new_model = construct_model_raw(get_full_model(set_pop(allAssociationDestinations(core, model_id, "instanceOf")))) model_overwrite(new_model, model_id) return "Success"! else: return string_join("Permission denied to model: ", read_attribute(core, type_id, "name"))! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_model_modify(user_id : String, model_name : String): // Model modify operation, which uses the mini_modify.alc operations, though with extensions for access control String model_id String type_id model_id = get_model_id(model_name) if (model_id != ""): if (allow_read(user_id, model_id)): type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf")) if (allow_read(user_id, type_id)): output("Success") modify(get_full_model(model_id), allow_write(user_id, model_id)) return "Success"! else: return string_join("Permission denied to model: ", read_attribute(core, type_id, "name"))! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_model_delete(user_id : String, model_name : String): String model_id model_id = get_model_id(model_name) if (model_id != ""): if (allow_write(user_id, model_id)): model_delete_element(core, model_id) return "Success"! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_model_list(): // List all models Element models String result String m result = "Success: " models = allInstances(core, "Model") while (read_nr_out(models) > 0): m = set_pop(models) result = (result + string_join((string_join(" ", read_attribute(core, m, "name")) + " : "), read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name"))) + "\n" return result! String function cmd_model_list_full(): // List all models with full info Element models String m String permissions String owner String group String name String type String result result = "Success: " 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") type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name") result = (result + (((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + name) + " : ") + type)) + "\n" return result! String function cmd_transformation_add_MANUAL(user_id : String, source_models : Element, target_models : Element, operation_name : String): return transformation_add(user_id, source_models, target_models, operation_name, "manual")! String function cmd_transformation_add_AL(user_id : String, source_models : Element, target_models : Element, operation_name : String): return transformation_add(user_id, source_models, target_models, operation_name, "actionlanguage")! String function transformation_add(user_id : String, source_models : Element, target_models : Element, operation_name : String, operation_type : String): // Add a manual transformation model String model_id Element models Element source Element target String name Element all_formalisms Element merged_formalism String merged_formalism_id String source_formalism_id String tracability_link String type_id String old_type_id Element keys String key source = create_node() target = create_node() all_formalisms = create_node() type_id = "" old_type_id = "" if (bool_and(read_nr_out(source_models) == 0, read_nr_out(target_models) == 0)): return "Cannot create transformation without input or output"! keys = dict_keys(source_models) while (read_nr_out(keys) > 0): key = set_pop(keys) name = source_models[key] model_id = get_model_id(name) if (model_id != ""): if (allow_read(user_id, model_id)): if (bool_not(dict_in(source, key))): type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf")) if (bool_or(old_type_id == "", type_id == old_type_id)): old_type_id = type_id dict_add(source, key, model_id) set_add(all_formalisms, create_tuple(name, get_full_model(model_id))) elif (old_type_id != type_id): // Already have a previous type_id and now another: CLASH return "Cannot add model as type not compatible with previous models: " + name! else: return "Model already selected as source: " + name! else: return "Permission denied to model: " + name! else: return "Model not found: " + name! keys = dict_keys(target_models) while (read_nr_out(keys) > 0): key = set_pop(keys) name = target_models[key] model_id = get_model_id(name) if (model_id != ""): if (allow_read(user_id, model_id)): if (bool_not(dict_in(target, key))): type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf")) if (bool_or(old_type_id == "", type_id == old_type_id)): old_type_id = type_id dict_add(target, key, model_id) set_add(all_formalisms, create_tuple(name, get_full_model(model_id))) elif (old_type_id != type_id): // Already have a previous type_id and now another: CLASH return "Cannot add mdoel as type not compatible with previous models: " + name! else: return "Model already selected as target: " + name! else: return "Permission denied to model: " + name! else: return "Model not found: " + name! if (get_model_id(operation_name) == ""): if (operation_type == "manual"): // Finished with all information, now create the model itself! model_create(instantiate_model(get_full_model(get_model_id("ManualOperation"))), operation_name, user_id, get_model_id("ManualOperation"), "ManualOperation") model_id = get_model_id(operation_name) elif (operation_type == "actionlanguage"): // Finished with all information, now create the model itself! output("Waiting for code constructors...") add_code_model(get_full_model(get_model_id("ActionLanguage")), "AL/" + operation_name, construct_function()) model_create(import_node("AL/" + operation_name), operation_name, user_id, get_model_id("ActionLanguage"), "ActionLanguage") model_id = get_model_id(operation_name) // Write out a merged metamodel containing all these models: this is the MM for the manual operation // New location is available, so write merged_formalism = model_fuse(set_copy(all_formalisms)) model_create(merged_formalism, "__merged_" + operation_name, user_id, type_id, "Model") merged_formalism_id = get_model_id("__merged_" + operation_name) // Add tracability links at this level while (read_nr_out(all_formalisms) > 0): source_formalism_id = get_model_id(list_read(set_pop(all_formalisms), 0)) tracability_link = instantiate_link(core, "tracability", "", merged_formalism_id, source_formalism_id) instantiate_attribute(core, tracability_link, "type", "merged") tracability_link = instantiate_link(core, "tracability", "", model_id, merged_formalism_id) instantiate_attribute(core, tracability_link, "type", "operatesOn") // Extend metadata with info on source and target String link String dst keys = dict_keys(source) while (read_nr_out(keys) > 0): key = set_pop(keys) link = instantiate_link(core, "transformInput", "", model_id, source[key]) instantiate_attribute(core, link, "name", key) keys = dict_keys(target) while (read_nr_out(keys) > 0): key = set_pop(keys) link = instantiate_link(core, "transformOutput", "", model_id, target[key]) instantiate_attribute(core, link, "name", key) return "Success"! else: return "Model exists: " + operation_name! String function cmd_transformation_add_MT(user_id : String, source_models : Element, target_models : Element, operation_name : String): // Add a model transformation model // Just a usual model instantiation, but need to add the source and target links based on user info String ramified_metamodel_id Element ramified_metamodel String model_id Element models Element links String link_id Element supported Element source Element target String name String new_model_id String merged_link_id Element links_merged String merged_formalism Element keys String key String mm Element to_ramify source = create_node() target = create_node() to_ramify = create_node() keys = dict_keys(source_models) while (read_nr_out(keys) > 0): key = set_pop(keys) name = source_models[key] model_id = get_model_id(name) if (model_id != ""): if (allow_read(user_id, name)): // Check whether or not it is SimpleClassDiagrams mm = read_attribute(core, readAssociationDestination(core, get_instanceOf_link(name)), "name") if (mm == "SimpleClassDiagrams"): if (bool_not(dict_in(source, key))): dict_add(source, key, model_id) dict_add(to_ramify, key, get_full_model(model_id)) else: return "Name was already assigned a metamodel: " + key! else: return "Model not supported for RAMification: " + name! else: return "Permission denied: " + name! else: return "Model not found: " + name! keys = dict_keys(target_models) while (read_nr_out(keys) > 0): key = set_pop(keys) name = target_models[key] model_id = get_model_id(name) if (model_id != ""): if (allow_read(user_id, name)): mm = read_attribute(core, readAssociationDestination(core, get_instanceOf_link(name)), "name") if (mm == "SimpleClassDiagrams"): if (bool_not(dict_in(target, key))): if (bool_not(dict_in(to_ramify, key))): dict_add(target, key, model_id) dict_add(to_ramify, key, get_full_model(model_id)) else: return "Name in output cannot have different type than input: " + key! else: return "Name was already assigned a metamodel: " + key! else: return "Model not supported for RAMification: " + name! else: return "Permission denied: " + name! else: return "Model not found: " + name! merged_formalism = model_fuse(to_ramify) ramified_metamodel = ramify(merged_formalism) model_create(ramified_metamodel, "__RAM_" + operation_name, user_id, get_model_id("SimpleClassDiagrams"), "Model") ramified_metamodel_id = get_model_id("__RAM_" + operation_name) // Now use the RAMified model to create the instance if (get_model_id(operation_name) == ""): String new_model // Finished with all information, now create the model itself! output("Waiting for model constructors...") new_model = construct_model_raw(get_full_model(ramified_metamodel_id)) model_create(new_model, operation_name, user_id, ramified_metamodel_id, "ModelTransformation") model_id = get_model_id(operation_name) // Extend metadata with info on source and target String link String dst keys = dict_keys(source) while (read_nr_out(keys) > 0): key = set_pop(keys) dst = source[key] link = instantiate_link(core, "transformInput", "", model_id, dst) instantiate_attribute(core, link, "name", key) keys = dict_keys(target) while (read_nr_out(keys) > 0): key = set_pop(keys) dst = target[key] link = instantiate_link(core, "transformOutput", "", model_id, dst) instantiate_attribute(core, link, "name", key) return "Success"! else: return "Model exists: " + operation_name! String function cmd_transformation_list(): // List all models Element models String m String type String result result = "Success: " models = allInstances(core, "Transformation") while (read_nr_out(models) > 0): m = set_pop(models) result = result + ((string_join(("[" + read_type(core, m)) + "]", string_join((string_join(" ", read_attribute(core, m, "name")) + " : "), read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")))) + "\n") return result! String function cmd_transformation_list_full(): // List all models with full info Element models String m String permissions String owner String group String name String type String result result = "" models = allInstances(core, "Transformation") 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") type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name") result = result + ((((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + ((("[" + read_type(core, m)) + "] ") + name)) + " : ") + type) + "\n") return result! String function cmd_permission_modify(user_id : String, model_name : String, permissions : String): Integer permission String model_id model_id = get_model_id(model_name) if (model_id != ""): if (get_relation_to_model(user_id, model_id) == 0): Boolean fail Integer i i = 0 if (string_len(permissions) != 3): fail = True while (i < 3): permission = cast_s2i(string_get(permissions, i)) if (bool_or(permission < 0, permission > 2)): fail = True break! i = i + 1 if (bool_not(fail)): unset_attribute(core, model_id, "permissions") instantiate_attribute(core, model_id, "permissions", permissions) return "Success"! else: return "Permission has incorrect format: must be a string of three characters, with each character being a digit between 0 and 2"! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_permission_owner(user_id : String, model_name : String, new_user_name : String): String model_id String new_user_id model_id = get_model_id(model_name) if (model_id != ""): if (bool_or(get_relation_to_model(user_id, model_id) == 0, is_admin(user_id))): new_user_id = get_user_id(new_user_name) if (new_user_id != ""): model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, model_id, "owner"))) instantiate_link(core, "owner", "", model_id, new_user_id) return "Success"! else: return "No such user: " + new_user_name! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_permission_group(user_id : String, model_name : String, new_group_name : String): String model_id String group_id model_id = get_model_id(model_name) if (model_id != ""): if (bool_or(get_relation_to_model(user_id, model_id) == 0, is_admin(user_id))): group_id = get_group_id(new_group_name) if (group_id != ""): model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, model_id, "group"))) instantiate_link(core, "group", "", model_id, group_id) return "Success"! else: return "No such group: " + new_group_name! else: return "Permission denied to model: " + model_name! else: return "Model not found: " + model_name! String function cmd_group_create(user_id : String, group_name : String): // Create a new group and become its owner String group_id String name group_id = get_group_id(group_name) if (group_id == ""): group_id = instantiate_node(core, "Group", "") instantiate_attribute(core, group_id, "name", group_name) instantiate_link(core, "belongsTo", "", user_id, group_id) instantiate_link(core, "owner", "", group_id, user_id) return "Success"! else: return "Group exists: " + group_name! String function cmd_group_delete(user_id : String, group_name : String): // Delete an existing group String group_id group_id = get_group_id(group_name) if (group_id != ""): if (allow_group_modify(user_id, group_id)): model_delete_element(core, group_id) return "Success"! else: return "Permission denied to group: " + group_name! else: return "Group not found: " + group_name! String function cmd_group_owner_add(user_id : String, group_name : String, other_user_name : String): // Add an owner to your group String group_id String other_user_id group_id = get_group_id(group_name) if (group_id != ""): if (allow_group_modify(user_id, group_id)): other_user_id = get_user_id(other_user_name) if (other_user_id != ""): Element overlap overlap = set_overlap(allIncomingAssociationInstances(core, other_user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner")) if (read_nr_out(overlap) == 0): instantiate_link(core, "owner", "", group_id, other_user_id) overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo")) if (read_nr_out(overlap) == 0): instantiate_link(core, "belongsTo", "", other_user_id, group_id) return "Success"! else: return "User is already the owner!"! else: return "User not found: " + other_user_name! else: return "Permission denied to group: " + group_name! else: return "Group not found: " + group_name! String function cmd_group_owner_delete(user_id : String, group_name : String, other_user_name : String): // Remove an owner from your group String group_id String other_user_id group_id = get_group_id(group_name) if (group_id != ""): if (allow_group_modify(user_id, group_id)): other_user_id = get_user_id(other_user_name) if (other_user_id != ""): Element overlap overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo")) if (read_nr_out(overlap) > 0): overlap = set_overlap(allIncomingAssociationInstances(core, other_user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner")) if (read_nr_out(overlap) > 0): model_delete_element(core, set_pop(overlap)) return "Success"! else: return "User is not an owner of the group!"! else: return "User is not a member of the group!"! else: return "User not found: " + other_user_name! else: return "Permission denied to group: " + group_name! else: return "Group not found: " + group_name! String function cmd_group_join(user_id : String, group_name : String, other_user_name : String): // Add someone to your group String group_id String other_user_id group_id = get_group_id(group_name) if (group_id != ""): if (allow_group_modify(user_id, group_id)): other_user_id = get_user_id(other_user_name) if (other_user_id != ""): Element overlap overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo")) if (read_nr_out(overlap) == 0): instantiate_link(core, "belongsTo", "", other_user_id, group_id) return "Success"! else: return "User is already a member of the group!"! else: return "User not found: " + other_user_name! else: return "Permission denied to group: " + group_name! else: return "Group not found: " + group_name! String function cmd_group_kick(user_id : String, group_name : String, other_user_name : String): // Remove someone from your group String group_id String other_user_id group_id = get_group_id(group_name) if (group_id != ""): if (allow_group_modify(user_id, group_id)): other_user_id = get_user_id(other_user_name) if (other_user_id != ""): Element overlap overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo")) if (read_nr_out(overlap) > 0): model_delete_element(core, set_pop(overlap)) // Check if user was an owner as well overlap = set_overlap(allIncomingAssociationInstances(core, other_user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner")) if (read_nr_out(overlap) > 0): model_delete_element(core, set_pop(overlap)) return "Success"! else: return "User is not a member of the group!"! else: return "User not found: " + other_user_name! else: return "Permission denied to group: " + group_name! else: return "Group not found: " + group_name! String function cmd_group_list(user_id : String): // List all groups you are a member of (and whether you are admin or not!) Element groups String group_id String admin String result result = "" groups = allAssociationDestinations(core, user_id, "belongsTo") while (read_nr_out(groups) > 0): group_id = set_pop(groups) if (set_in(allOutgoingAssociationInstances(core, group_id, "owner"), user_id)): admin = " A " else: admin = " " result = result + (string_join(admin, read_attribute(core, group_id, "name")) + "\n") return result! String function cmd_admin_promote(user_id : String, other_user_name : String): // Promote a user to admin status if (is_admin(user_id)): String other_user_id other_user_id = get_user_id(other_user_name) if (other_user_id != ""): unset_attribute(core, other_user_id, "admin") instantiate_attribute(core, other_user_id, "admin", True) return "Success"! else: return "User not found: " + other_user_name! else: return "Permission denied to administrate: " + other_user_name! String function cmd_admin_demote(user_id : String, other_user_name : String): // Demote a user to normal status if (is_admin(user_id)): String other_user_id other_user_id = get_user_id(other_user_name) if (other_user_id != ""): unset_attribute(core, other_user_id, "admin") instantiate_attribute(core, other_user_id, "admin", False) return "Success"! else: return "User not found: " + other_user_name! else: return "Permission denied to administrate: " + other_user_name! Void function user_function_skip_init(user_id : String): String cmd output("Welcome to the Model Management Interface v2.0!") output("Use the 'help' command for a list of possible commands") while (True): cmd = input() if (cmd == "help"): output(cmd_help(user_id)) elif (cmd == "model_add"): output(cmd_model_add(user_id, single_input("Model type?"), single_input("Model name?"))) elif (cmd == "process_execute"): output(cmd_process_execute(user_id, single_input("Process to execute?"), single_input("Model prefix to use?"))) elif (cmd == "transformation_between"): output(cmd_transformation_between(user_id, single_input("Source type?"), single_input("Target type?"))) elif (cmd == "model_render"): output(cmd_model_render(user_id, single_input("Model name?"), single_input("Mapper name?"))) elif (cmd == "transformation_execute"): output(cmd_transformation_execute(user_id, single_input("Transformation name?"), dict_input("Source models?"), dict_input("Target models?"))) elif (cmd == "verify"): output(cmd_verify(user_id, single_input("Model name?"))) elif (cmd == "model_overwrite"): output(cmd_model_overwrite(user_id, single_input("Model name?"))) elif (cmd == "model_modify"): output(cmd_model_modify(user_id, single_input("Model name?"))) elif (cmd == "model_delete"): output(cmd_model_delete(user_id, single_input("Model name?"))) elif (cmd == "model_list"): output(cmd_model_list()) elif (cmd == "model_list_full"): output(cmd_model_list_full()) elif (cmd == "transformation_add_MANUAL"): output(cmd_transformation_add_MANUAL(user_id, dict_input("Source model names?"), dict_input("Target model names?"), single_input("Operation name?"))) elif (cmd == "transformation_add_AL"): output(cmd_transformation_add_AL(user_id, dict_input("Source model names?"), dict_input("Target model names?"), single_input("Operation name?"))) elif (cmd == "transformation_add_MT"): output(cmd_transformation_add_MT(user_id, dict_input("Source model names?"), dict_input("Target models?"), single_input("Operation name?"))) elif (cmd == "transformation_list"): output(cmd_transformation_list()) elif (cmd == "transformation_list_full"): output(cmd_transformation_list_full()) elif (cmd == "permission_modify"): output(cmd_permission_modify(user_id, single_input("Model name?"), single_input("Permissions?"))) elif (cmd == "permission_owner"): output(cmd_permission_owner(user_id, single_input("Model name?"), single_input("New owning user?"))) elif (cmd == "permission_group"): output(cmd_permission_group(user_id, single_input("Model name?"), single_input("New owning group?"))) elif (cmd == "group_create"): output(cmd_group_create(user_id, single_input("New group name?"))) elif (cmd == "group_delete"): output(cmd_group_delete(user_id, single_input("Group name?"))) elif (cmd == "group_owner_add"): output(cmd_group_owner_add(user_id, single_input("Group name?"), single_input("User name?"))) elif (cmd == "group_owner_delete"): output(cmd_group_owner_delete(user_id, single_input("Group name?"), single_input("User name?"))) elif (cmd == "group_join"): output(cmd_group_join(user_id, single_input("Group name?"), single_input("User name?"))) elif (cmd == "group_kick"): output(cmd_group_kick(user_id, single_input("Group name?"), single_input("User name?"))) elif (cmd == "group_list"): output(cmd_group_list(user_id)) elif (cmd == "admin_promote"): output(cmd_admin_promote(user_id, single_input("User name?"))) elif (cmd == "admin_demote"): output(cmd_admin_demote(user_id, single_input("User name?"))) elif (cmd == "verbose"): set_verbose(True) elif (cmd == "quiet"): set_verbose(False) elif (cmd == "self-destruct"): // Delete user from Core Formalism model_delete_element(core, user_id) return ! 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 // as the current user will have been deleted return ! else: output("Unknown command: " + cmd) // We never get here! return !