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 core_location = "models/CoreFormalism" String core_model_location = "core" Void function main(): // 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 String pm_model String coreM_model_location String pm_location String scd_location String al_location coreM_model_location = "models/core" pm_location = "models/ProcessModel" scd_location = "models/SimpleClassDiagrams" al_location = "models/ActionLanguage" scd = import_node(scd_location) al = import_node(al_location) pm = import_node(pm_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"]) // Switch all new users to the user_function // This accesses the bootstrap level, so do not change this unless you know what you are doing Element root Element prev root = read_root() root = root["__hierarchy"]["__IP"] while (value_neq(root, !call)): prev = root root = root["next"] dict_delete(prev, "next") dict_add(prev, "next", user_function["body"]) // 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", "") output("Desired username for admin user?") instantiate_attribute(core, admin_user, "name", input()) instantiate_attribute(core, admin_user, "admin", True) String password while (True): output("Desired password for admin user?") password = hash(input()) output("Please repeat the password") if (password == hash(input())): output("Passwords match!") instantiate_attribute(core, admin_user, "password", password) break! else: output("Not the same password, please try again!") // 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"]) // Make necessary links for the formalism to the owners instantiate_link(core, "group", "", scd_model, admin_group) instantiate_link(core, "owner", "", scd_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"]) // Make necessary links for the formalism to the owners 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"]) // Make necessary links for the formalism to the owners instantiate_link(core, "group", "", al_model, admin_group) instantiate_link(core, "owner", "", al_model, admin_user) // Add the Manual Operation formalism log("Adding manual model") 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()) log("Added manual model") // Make necessary links for the formalism to the owners instantiate_link(core, "group", "", manual_model, admin_group) instantiate_link(core, "owner", "", manual_model, admin_user) // 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"]) // Make necessary links for the formalism to the owners 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"]) // Make necessary links for the formalism to the owners 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!") user_function_skip_init(admin_user) // Done, so finish up // Admin user will have been deleted by the user_function as usual // Note that if there are no admin users left, it will be very difficult to manage, as nobody will have admin permissions! 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()! Element function user_function(): String username String user_id String password // Load in all global variables, as this code is hotloaded! Element root root = read_root() root = root["__hierarchy"]["objects"] exec(root["bootstrap/modelling.alc"]["initializers"]) exec(root["bootstrap/library.alc"]["initializers"]) exec(root["bootstrap/constructors.alc"]["initializers"]) exec(root["bootstrap/object_operations.alc"]["initializers"]) exec(root["core/mini_modify.alc"]["initializers"]) exec(root["bootstrap/model_management.alc"]["initializers"]) exec(root["bootstrap/ramify.alc"]["initializers"]) exec(root["bootstrap/transform.alc"]["initializers"]) exec(root["bootstrap/conformance_scd.alc"]["initializers"]) exec(root["core/core_algorithm.alc"]["initializers"]) // Load in a hard-reference to the previously created model core = import_node(core_model_location) 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) while (True): output("This is a new user: please give password!") password = hash(input()) output("Please repeat the password") if (password == hash(input())): output("Passwords match!") output("User created") instantiate_attribute(core, user_id, "password", password) break! else: output("Not the same password, please try again!") // Now call with user created user_function_skip_init(user_id) else: while (bool_not(check_login(user_id))): output("Wrong password! Try again") user_function_skip_init(user_id) // User destroyed already, so just stop execution // TODO return a fresh node as otherwise the compiler doesn't take this return create_node()! 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(worklist, read_edge_dst(read_out(finished, i)))): return True! i = i + 1 return False! 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 inputs = create_node() outputs = create_node() output_mms = create_node() // TODO use the prefix for data locations (in model write/read in MvC) log("Enacting action " + cast_v2s(read_attribute(pm, element, "name"))) // Read out the referenced element from the MvC transformation_id = get_model_id(read_attribute(pm, element, "name")) // Find all inputs and their types (i.e., key) lst = allAssociationOrigins(pm, element, "Consumes") while (read_nr_out(lst) > 0): elem = set_pop(lst) log("Origin: " + elem) // As there are no inheritance relations between full models, we can just read out the typename type_name = read_attribute(pm, elem, "type") dict_add(inputs, type_name, string_join(prefix, read_attribute(pm, elem, "name"))) log("Inputs: " + dict_to_string(inputs)) // Find all outputs and their types (i.e., key) log("Read all producers of " + element) lst = allAssociationDestinations(pm, element, "Produces") while (read_nr_out(lst) > 0): elem = set_pop(lst) log("Destination: " + elem) // As there are no inheritance relations between full models, we can just read out the typename type_name = read_attribute(pm, elem, "type") log("Type name: " + type_name) dict_add(outputs, type_name, string_join(prefix, read_attribute(pm, elem, "name"))) dict_add(output_mms, type_name, get_full_model(get_model_id(type_name))) log("Outputs: " + dict_to_string(outputs)) exact_type = read_type(core, transformation_id) log("Exact type: " + exact_type) log("EXECUTE OPERATION " + cast_e2s(read_attribute(core, transformation_id, "name"))) if (exact_type == "ModelTransformation"): // Model transformation is always in-place and uses only a single metamodel // Therefore, we must: // 1) Create an empty model, instance of merged metamodel // 2) Merge the different source models and retype // 3) Perform the transformation on the merged model // 4) Split the resulting model based on the target formalisms // Element input_model Element schedule_model String trace_link_id Element merged_model String merged_metamodel_id String ramified_metamodel_id schedule_model = get_full_model(transformation_id) // 1) Create empty instance of merged metamodel ramified_metamodel_id = set_pop(followAssociation(core, transformation_id, "instanceOf")) log("Got ramified: " + ramified_metamodel_id) trace_links = allOutgoingAssociationInstances(core, ramified_metamodel_id, "tracability") log("Trace links resolved") 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"), "RAMified")): merged_metamodel_id = readAssociationDestination(core, trace_link_id) log("Got merged metamodel: " + merged_metamodel_id) if (merged_metamodel_id != ""): log("Ready for instantiate") merged_model = instantiate_model(get_full_model(merged_metamodel_id)) log("Instantiated model") // 2) Merge source models String key Element keys Element input_keys Element output_keys log("Fetching input keys") input_keys = dict_keys(inputs) log("Input keys: " + set_to_string(input_keys)) while (read_nr_out(input_keys) > 0): key = set_pop(input_keys) model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/") // 3) Transform result = transform(merged_model, schedule_model) // 4) Split in different files depending on type String desired_metamodel_id Element split_off_model output_keys = dict_keys(outputs) while (read_nr_out(output_keys) > 0): key = set_pop(output_keys) desired_metamodel_id = get_model_id(key) split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/") // Check if the destination model already exists if (get_model_id(outputs[key]) == ""): // New model model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model") else: // Model exists, so we overwrite model_overwrite(split_off_model, get_model_id(outputs[key])) else: log("Intermediate not found") elif (exact_type == "ActionLanguage"): Element dictionary Element new_inputs Element input_keys Element output_keys Element result String key Element func log("Action Language execution starts!") log("Getting full model for transformation") log("Got model: " + cast_e2s(read_attribute(core, transformation_id, "location"))) // 1) Group source models in dictionary // --> This is just the "inputs" variable, but resolve all references log("Create inputs") new_inputs = create_node() input_keys = dict_keys(inputs) while (read_nr_out(input_keys) > 0): key = set_pop(input_keys) log("Resolving " + cast_e2s(key)) log(" --> " + cast_e2s(inputs[key])) log(" ID " + cast_e2s(get_model_id(inputs[key]))) log(" full m " + cast_e2s(get_full_model(get_model_id(inputs[key])))) dict_add(new_inputs, key, get_full_model(get_model_id(inputs[key]))) inputs = new_inputs // 2) Execute action language model func = get_func_AL_model(get_full_model(transformation_id)) log("Ready to execute: " + cast_e2s(func)) result = func(inputs, output_mms) log("Result: " + cast_e2s(result)) // 3) Split output dictionary back to seperate models output_keys = dict_keys(outputs) while (read_nr_out(output_keys) > 0): key = set_pop(output_keys) log("Splitting " + key) // Check if the destination model already exists if (get_model_id(outputs[key]) == ""): // New model model_create(result[key], outputs[key], user_id, get_model_id(key), "Model") else: // Model exists, so we overwrite model_overwrite(result[key], get_model_id(outputs[key])) log("Finished") elif (exact_type == "ManualOperation"): log("Manual operation starts!") // Identical to model transformations, but give control to users for modification // 1) Create empty instance of merged metamodel Element input_model String trace_link_id Element merged_model String merged_metamodel_id trace_links = allOutgoingAssociationInstances(core, transformation_id, "tracability") 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"), "operatesOn")): merged_metamodel_id = readAssociationDestination(core, trace_link_id) if (merged_metamodel_id != ""): merged_model = instantiate_model(get_full_model(merged_metamodel_id)) // 2) Merge source models String key Element keys Element input_keys Element output_keys input_keys = dict_keys(inputs) while (read_nr_out(input_keys) > 0): key = set_pop(input_keys) model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/") // 3) Transform log("Start modify") modify(merged_model, True) log("Modify finished") // 4) Split in different files depending on type String desired_metamodel_id Element split_off_model output_keys = dict_keys(outputs) while (read_nr_out(output_keys) > 0): key = set_pop(output_keys) desired_metamodel_id = get_model_id(key) split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/") // Check if the destination model already exists log("Writing output to " + cast_v2s(outputs[key])) if (get_model_id(outputs[key]) == ""): // New model model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model") else: // Model exists, so we overwrite model_overwrite(split_off_model, get_model_id(outputs[key])) else: output("Could not find merged metamodel") // TODO find out whether it succeeded or not result = True else: log("Type name: " + exact_type) log("From " + transformation_id) output("Did not know how to interpret model of type " + exact_type) return result! 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 // 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] log("EXECUTING " + element) // 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"): // Just fork, so we have multiple outgoing // Not a problem, as we already can do this with the usual code 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) log("Executed Exec of " + element) log("Result: " + cast_v2s(result)) 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! // 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) log("Queueing next: " + next) set_add(worklist, create_tuple(next, result)) // Reached a finish element, so stop return ! 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): 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_list -- List all models") output(" model_list_full -- List all models with full info") output(" model_overwrite -- Overwrites a model with an uploaded model, leaving all metadata") output(" verify -- Check whether a model conforms to its metamodel") output("") output("Transformation-specific operations") output(" transformation_add_MT_language -- Create a RAMified metamodel of a set of models") output(" transformation_add_MT -- Initialize a new model transformation") output(" transformation_add_AL -- Initialize a new action language transformation") output(" transformation_add_MANUAL -- Initialize a new manual transformation") output(" transformation_execute -- Execute a transformation on a set of input models") output(" transformation_list -- List all model transformations") output(" transformation_list_full -- List all model transformations with permissions") output(" transformation_detail -- List transformation details") output(" transformation_RAMify -- RAMify a metamodel (again)") output("") output("Process operations") output(" process_execute -- Execute a process model") output("") output("Model permission operations") output(" permission_modify -- Change model permissions") output(" permission_owner -- Change model owner") output(" permission_group -- Change model group") output("") output("Group operations") output(" group_create -- Create a group") output(" group_delete -- Delete a group") output(" group_owner_add -- Add group owner") output(" group_owner_delete -- Remove group owner") output(" group_join -- Add someone to your group") output(" group_kick -- Kick someone from your group") output(" group_list -- List all groups you are a member of") 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(" self-destruct -- Remove current user and revoke all permissions ") output(" exit -- Kill the current task, while retaining user") elif (cmd == "model_add"): // Model addition operation, which uses model upload commands of the compiler String name String type String location String type_id Element new_model String new_model_id 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...") new_model = construct_model_raw(get_full_model(type_id)) model_create(new_model, name, user_id, type_id, "Model") output("Model upload success!") else: output("Model with that name already exists!") else: output("Permission denied") else: output("Could not find type model!") elif (cmd == "process_execute"): // Execute a process model until it reaches termination String process_id output("Which process model do you want to execute?") log("Execute process!") process_id = get_model_id(input()) if (process_id != ""): if (allow_read(user_id, process_id)): output("Model prefix to use?") enact_PM(get_full_model(process_id), input(), user_id) else: output("Permission denied") else: output("No such model") elif (cmd == "transformation_execute"): // 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 String name_id Element inputs Element outputs Element trace_links String target_model_name String source_model_name output("Which transformation do you want to execute?") transformation_id = get_model_id(input()) if (transformation_id != ""): if (allow_read(user_id, transformation_id)): if (is_nominal_instance(core, transformation_id, "Transformation")): // Read out source and target links sources = allOutgoingAssociationInstances(core, transformation_id, "transformInput") inputs = create_node() while (read_nr_out(sources) > 0): source = set_pop(sources) output(string_join("Which model to bind for source element ", read_attribute(core, source, "name"))) source_model_name = input() name_id = get_model_id(source_model_name) if (name_id != ""): if (allow_read(user_id, name_id)): // Check for conformance to the specified metamodel! Element specified_model // TODO Maybe find out which conformance relation to use, as there might be multiple! if (check_is_typed_by(name_id, source)): if (check_conformance(name_id)): dict_add(inputs, read_attribute(core, source, "name"), source_model_name) else: output("Model has correct type but does not conform completely!") set_add(sources, source) else: output("Model has different type!") set_add(sources, source) else: output("Permission denied") set_add(sources, source) else: output("No such model") set_add(sources, source) targets = allOutgoingAssociationInstances(core, transformation_id, "transformOutput") outputs = create_node() while (read_nr_out(targets) > 0): target = set_pop(targets) output(string_join("Which model to create for target element ", read_attribute(core, target, "name"))) target_model_name = input() if (get_model_id(target_model_name) == ""): // Doesn't exist yet, so we can easily create dict_add(outputs, read_attribute(core, target, "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(outputs, read_attribute(core, target, "name"), target_model_name) else: output("Permission denied; try again") exact_type = read_type(core, transformation_id) if (exact_type == "ModelTransformation"): // Model transformation is always in-place and uses only a single metamodel // Therefore, we must: // 1) Create an empty model, instance of merged metamodel // 2) Merge the different source models and retype // 3) Perform the transformation on the merged model // 4) Split the resulting model based on the target formalisms // Element input_model Element schedule_model String trace_link_id Element merged_model String merged_metamodel_id String ramified_metamodel_id Boolean result schedule_model = get_full_model(transformation_id) // 1) Create empty instance of merged metamodel ramified_metamodel_id = set_pop(followAssociation(core, transformation_id, "instanceOf")) trace_links = allOutgoingAssociationInstances(core, ramified_metamodel_id, "tracability") 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"), "RAMified")): merged_metamodel_id = readAssociationDestination(core, trace_link_id) if (merged_metamodel_id != ""): merged_model = instantiate_model(get_full_model(merged_metamodel_id)) // 2) Merge source models String key Element keys Element input_keys Element output_keys input_keys = dict_keys(inputs) while (read_nr_out(input_keys) > 0): key = set_pop(input_keys) model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/") // 3) Transform log("EXECUTE TRANSFORMATION " + cast_e2s(read_attribute(core, transformation_id, "name"))) result = transform(merged_model, schedule_model) output("Transformation executed with result: " + cast_v2s(result)) // 4) Split in different files depending on type String desired_metamodel_id Element split_off_model output_keys = dict_keys(outputs) while (read_nr_out(output_keys) > 0): key = set_pop(output_keys) desired_metamodel_id = get_model_id(key) split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/") // Check if the destination model already exists if (get_model_id(outputs[key]) == ""): // New model model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model") else: // Model exists, so we overwrite model_overwrite(split_off_model, get_model_id(outputs[key])) else: output("Could not resolve intermediate merged metamodel") elif (exact_type == "ActionLanguage"): Element dictionary Element new_inputs Element input_keys Element output_keys Element result String key Element func log("Action Language execution starts!") log("Getting full model for transformation") log("Got model: " + cast_e2s(read_attribute(core, transformation_id, "location"))) // 1) Group source models in dictionary // --> This is just the "inputs" variable, but resolve all references log("Create inputs") new_inputs = create_node() input_keys = dict_keys(inputs) while (read_nr_out(input_keys) > 0): key = set_pop(input_keys) log("Resolving " + cast_e2s(key)) log(" --> " + cast_e2s(inputs[key])) log(" ID " + cast_e2s(get_model_id(inputs[key]))) log(" full m " + cast_e2s(get_full_model(get_model_id(inputs[key])))) dict_add(new_inputs, key, get_full_model(get_model_id(inputs[key]))) inputs = new_inputs // 2) Execute action language model func = get_func_AL_model(get_full_model(transformation_id)) log("Ready to execute: " + cast_e2s(func)) result = func(inputs) log("Result: " + cast_e2s(result)) // 3) Split output dictionary back to seperate models output_keys = dict_keys(outputs) while (read_nr_out(output_keys) > 0): key = set_pop(output_keys) log("Splitting " + key) // Check if the destination model already exists if (get_model_id(outputs[key]) == ""): // New model model_create(result[key], outputs[key], user_id, get_model_id(key), "Model") else: // Model exists, so we overwrite model_overwrite(result[key], get_model_id(outputs[key])) log("Finished") elif (exact_type == "ManualOperation"): log("Manual operation starts!") // Identical to model transformations, but give control to users for modification // 1) Create empty instance of merged metamodel Element input_model String trace_link_id Element merged_model String merged_metamodel_id trace_links = allOutgoingAssociationInstances(core, transformation_id, "tracability") 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"), "operatesOn")): merged_metamodel_id = readAssociationDestination(core, trace_link_id) if (merged_metamodel_id != ""): merged_model = instantiate_model(get_full_model(merged_metamodel_id)) // 2) Merge source models String key Element keys Element input_keys Element output_keys input_keys = dict_keys(inputs) while (read_nr_out(input_keys) > 0): key = set_pop(input_keys) model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/") // 3) Transform log("Start modify") modify(merged_model, True) log("Modify finished") // 4) Split in different files depending on type String desired_metamodel_id Element split_off_model output_keys = dict_keys(outputs) while (read_nr_out(output_keys) > 0): key = set_pop(output_keys) desired_metamodel_id = get_model_id(key) split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/") // Check if the destination model already exists if (get_model_id(outputs[key]) == ""): // New model model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model") else: // Model exists, so we overwrite model_overwrite(split_off_model, get_model_id(outputs[key])) else: output("Could not find merged metamodel") else: output("Did not know how to interpret model of type " + exact_type) else: output("Model is not an executable transformation") else: output("Permission denied") else: output("No such transformation") elif (cmd == "verify"): // Check whether a model conforms to its specification (with the selected type mapping) String model_id String result output("Which model to verify?") model_id = get_model_id(input()) if (model_id != ""): if (allow_read(user_id, model_id)): result = conformance_scd(get_full_model(model_id)) output(result) else: output("Permission denied") else: output("No such model") elif (cmd == "model_overwrite"): // Overwrites an existing model without changing any metadata String model_id Element new_model output("Which model to overwrite?") model_id = get_model_id(input()) if (model_id != ""): if (allow_write(user_id, model_id)): if (allow_read(user_id, set_pop(followAssociation(core, model_id, "instanceOf")))): output("Waiting for model constructors...") new_model = construct_model_raw(get_full_model(set_pop(followAssociation(core, model_id, "instanceOf")))) model_overwrite(new_model, model_id) output("Model overwrite success!") else: output("Permission denied") else: output("Permission denied") else: output("No such model") elif (cmd == "model_modify"): // Model modify operation, which uses the mini_modify.alc operations, though with extensions for access control String model_id String type_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)): type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf")) if (allow_read(user_id, type_id)): modify(get_full_model(model_id), allow_write(user_id, model_id)) else: output("Permission denied") else: output("Permission denied") 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(string_join((string_join(" ", read_attribute(core, m, "name")) + " : "), read_attribute(core, set_pop(followAssociation(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") type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name") output(((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + name) + " : ") + type) elif (cmd == "transformation_add_MT_language"): // Create a model transformation language from a set of input and output formalisms String name String model_id Element source Element target Element all_formalisms Element merged_formalism Element ramified_formalism String old_type_id String type_id String location String new_model_id old_type_id = "" log("Adding MT language") // Read involved formalisms all_formalisms = create_node() output("Formalisms to include (terminate with empty string)?") name = input() while (name != ""): model_id = get_model_id(name) if (model_id != ""): if (allow_read(user_id, model_id)): type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf")) if (bool_or(old_type_id == "", type_id == old_type_id)): set_add(all_formalisms, create_tuple(name, get_full_model(model_id))) old_type_id = type_id elif (old_type_id != type_id): // Already have a previous type_id and now another: CLASH output("Cannot add model as types not compatible with previous models; try again") else: output("Model not readable; try again") else: output("No such model; try again") name = input() // Merge all into a single metamodel if (read_nr_out(all_formalisms) > 0): output("Name of the RAMified transformation metamodel?") name = input() if (get_model_id(name) == ""): String merged_formalism_id String ramified_formalism_id String source_formalism_id String tracability_link // New location is available, so write log("FUSE") merged_formalism = model_fuse(set_copy(all_formalisms)) log("Fuse OK") model_create(merged_formalism, "__merged_" + name, user_id, type_id, "Model") merged_formalism_id = get_model_id("__merged_" + 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") // Merge complete, now RAMify! log("RAM") ramified_formalism = ramify(merged_formalism) log("RAMed") model_create(ramified_formalism, name, user_id, type_id, "Model") ramified_formalism_id = get_model_id(name) // Add tracability link at this level tracability_link = instantiate_link(core, "tracability", "", ramified_formalism_id, merged_formalism_id) instantiate_attribute(core, tracability_link, "type", "RAMified") else: output("Model already exists!") else: output("At least one formalism is required") elif (cmd == "transformation_RAMify"): // RAMify a metamodel String merged_model_id String target_model_name String target_model_id Element target_model String tracability_link output("Which metamodel do you want to RAMify?") merged_model_id = get_model_id(input()) if (merged_model_id != ""): if (allow_read(user_id, merged_model_id)): output("Where do you want to store the RAMified metamodel?") target_model_name = input() target_model_id = get_model_id(target_model_name) if (target_model_id == ""): // New model, so everything is fine target_model = ramify(get_full_model(merged_model_id)) model_create(target_model, target_model_name, user_id, set_pop(allAssociationDestinations(core, merged_model_id, "instanceOf")), "Model") target_model_id = get_model_id(target_model_name) tracability_link = instantiate_link(core, "tracability", "", target_model_id, merged_model_id) instantiate_attribute(core, tracability_link, "type", "RAMified") else: // Existing model, so overwrite if (allow_write(user_id, target_model_id)): target_model = ramify(get_full_model(merged_model_id)) model_overwrite(target_model, target_model_id) model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, target_model_id, "tracability"))) tracability_link = instantiate_link(core, "tracability", "", target_model_id, merged_model_id) instantiate_attribute(core, tracability_link, "type", "RAMified") else: output("Permission denied") else: output("Permission denied!") else: output("No such model") elif (cmd == "transformation_add_MANUAL"): // Add a manual transformation model output("Which metamodels do you want to use as source for the manual operation (empty string to finish)?") 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 name = input() source = create_node() target = create_node() all_formalisms = create_node() type_id = "" old_type_id = "" while (name != ""): model_id = get_model_id(name) if (model_id != ""): if (allow_read(user_id, model_id)): if (bool_not(set_in(source, model_id))): 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 set_add(source, model_id) set_add(all_formalisms, create_tuple(name, get_full_model(model_id))) output("Model added as source") elif (old_type_id != type_id): // Already have a previous type_id and now another: CLASH output("Cannot add model as types not compatible with previous models; try again") else: output("Model already selected as source") else: output("Permission denied") else: output("No such model; try again") name = input() output("Which metamodels do you want to use as target for the manual operation (empty string to finish)?") name = input() while (name != ""): model_id = get_model_id(name) if (model_id != ""): if (allow_read(user_id, model_id)): if (bool_not(set_in(target, model_id))): 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 set_add(target, model_id) set_add(all_formalisms, create_tuple(name, get_full_model(model_id))) output("Model added as target") elif (old_type_id != type_id): // Already have a previous type_id and now another: CLASH output("Cannot add model as types not compatible with previous models; try again") else: output("Model already selected as target") else: output("Permission denied") else: output("No such model; try again") name = input() output("Name of Manual operation model?") name = input() if (get_model_id(name) == ""): // Finished with all information, now create the model itself! model_create(instantiate_model(get_full_model(get_model_id("ManualOperation"))), name, user_id, get_model_id("ManualOperation"), "ManualOperation") model_id = get_model_id(name) // Write out a merged metamodel containing all these models: this is the MM for the manual operation // New location is available, so write log("FUSE") merged_formalism = model_fuse(set_copy(all_formalisms)) log("Fuse OK") model_create(merged_formalism, "__merged_" + name, user_id, type_id, "Model") merged_formalism_id = get_model_id("__merged_" + 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 log("Adding inputs") while (read_nr_out(source) > 0): dst = set_pop(source) log(" for " + dst) link = instantiate_link(core, "transformInput", "", model_id, dst) instantiate_attribute(core, link, "name", read_attribute(core, dst, "name")) log("Adding outputs") while (read_nr_out(target) > 0): dst = set_pop(target) log(" for " + dst) link = instantiate_link(core, "transformOutput", "", model_id, dst) instantiate_attribute(core, link, "name", read_attribute(core, dst, "name")) else: output("Model already exists") elif (cmd == "transformation_add_AL"): // Add an action language transformation model output("Which metamodels do you want to use as source for the action code (empty string to finish)?") String model_id Element models Element source Element target String name name = input() source = create_node() target = create_node() while (name != ""): model_id = get_model_id(name) if (model_id != ""): if (bool_not(set_in(source, model_id))): set_add(source, model_id) output("Model added as source") else: output("Model already selected as source") else: output("No such model; try again") name = input() output("Which metamodels do you want to use as target for the action code (empty string to finish)?") name = input() while (name != ""): model_id = get_model_id(name) if (model_id != ""): if (bool_not(set_in(target, model_id))): set_add(target, model_id) output("Model added as target") else: output("Model already selected as target") else: output("No such model; try again") name = input() output("Name of Action Language model?") name = input() log("Add AL is fine!") if (get_model_id(name) == ""): // Finished with all information, now create the model itself! output("Waiting for model constructors...") log("AL model: " + cast_e2s(get_model_id("ActionLanguage"))) log("Location: " + cast_e2s(read_attribute(core, get_model_id("ActionLanguage"), "location"))) log("Imported: " + cast_e2s(import_node(read_attribute(core, get_model_id("ActionLanguage"), "location")))) add_code_model(get_full_model(get_model_id("ActionLanguage")), "AL/" + name, construct_function()) log("Exported to " + cast_e2s(import_node("AL/" + name))) model_create(import_node("AL/" + name), name, user_id, get_model_id("ActionLanguage"), "ActionLanguage") model_id = get_model_id(name) // Extend metadata with info on source and target String link String dst log("Adding inputs") while (read_nr_out(source) > 0): dst = set_pop(source) log(" for " + dst) link = instantiate_link(core, "transformInput", "", model_id, dst) instantiate_attribute(core, link, "name", read_attribute(core, dst, "name")) log("Adding outputs") while (read_nr_out(target) > 0): dst = set_pop(target) log(" for " + dst) link = instantiate_link(core, "transformOutput", "", model_id, dst) instantiate_attribute(core, link, "name", read_attribute(core, dst, "name")) else: output("Model already exists") elif (cmd == "transformation_add_MT"): // 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 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_metamodel_id source = create_node() target = create_node() supported = create_node() output("RAMified metamodel to use?") ramified_metamodel_id = get_model_id(input()) if (ramified_metamodel_id != ""): if (allow_read(user_id, ramified_metamodel_id)): output("Supported metamodels:") links = allOutgoingAssociationInstances(core, ramified_metamodel_id, "tracability") while (read_nr_out(links) > 0): link_id = set_pop(links) merged_metamodel_id = readAssociationDestination(core, link_id) if (value_eq(read_attribute(core, link_id, "type"), "RAMified")): links_merged = allOutgoingAssociationInstances(core, merged_metamodel_id, "tracability") while (read_nr_out(links_merged) > 0): merged_link_id = set_pop(links_merged) if (value_eq(read_attribute(core, merged_link_id, "type"), "merged")): output(string_join(" ", read_attribute(core, readAssociationDestination(core, merged_link_id), "name"))) set_add(supported, readAssociationDestination(core, merged_link_id)) output("") output("Which ones do you want to use as source (empty string to finish)?") name = input() while (name != ""): model_id = get_model_id(name) if (model_id != ""): if (set_in(supported, model_id)): if (bool_not(set_in(source, model_id))): set_add(source, model_id) output("Model added as source") else: output("Model already selected as source") else: output("Model is not supported by RAMified metamodel!") else: output("No such model; try again") name = input() output("Which ones do you want to use as target (empty string to finish)?") name = input() while (name != ""): model_id = get_model_id(name) if (model_id != ""): if (set_in(supported, model_id)): if (bool_not(set_in(target, model_id))): set_add(target, model_id) output("Model added as target") else: output("Model already selected as target") else: output("Model is not supported by RAMified metamodel!") else: output("No such model; try again") name = input() output("Name of new transformation?") name = input() if (get_model_id(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, name, user_id, ramified_metamodel_id, "ModelTransformation") model_id = get_model_id(name) // Extend metadata with info on source and target String link String dst while (read_nr_out(source) > 0): dst = set_pop(source) link = instantiate_link(core, "transformInput", "", model_id, dst) instantiate_attribute(core, link, "name", read_attribute(core, dst, "name")) while (read_nr_out(target) > 0): dst = set_pop(target) link = instantiate_link(core, "transformOutput", "", model_id, dst) instantiate_attribute(core, link, "name", read_attribute(core, dst, "name")) else: output("Model already exists") else: output("Permission denied") else: output("No such model") elif (cmd == "transformation_list"): // List all models Element models String m String type models = allInstances(core, "Transformation") while (read_nr_out(models) > 0): m = set_pop(models) output(string_join(("[" + read_type(core, m)) + "]", string_join((string_join(" ", read_attribute(core, m, "name")) + " : "), read_attribute(core, set_pop(followAssociation(core, m, "instanceOf")), "name")))) elif (cmd == "transformation_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, "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") output(((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + ((("[" + read_type(core, m)) + "] ") + name)) + " : ") + type) elif (cmd == "permission_modify"): String permissions Integer permission String model_id output("Which model do you want to change permissions of?") model_id = get_model_id(input()) if (model_id != ""): if (get_relation_to_model(user_id, model_id) == 0): output("New permissions?") permissions = input() 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) else: output("Permissions must be a string of three characters with each character being a digit between 0 and 2") else: output("Permission denied!") else: output("No such model!") elif (cmd == "permission_owner"): String permissions String model_id String user_id output("Which model do you want to change owner of?") model_id = get_model_id(input()) if (model_id != ""): if (bool_or(get_relation_to_model(user_id, model_id) == 0, is_admin(user_id))): output("New owner?") user_id = get_user_id(input()) if (user_id != ""): model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, model_id, "owner"))) instantiate_link(core, "owner", "", model_id, user_id) else: output("No such user!") else: output("Permission denied!") else: output("No such model!") elif (cmd == "permission_group"): String permissions String model_id String group_id output("Which model do you want to change permissions of?") model_id = get_model_id(input()) if (model_id != ""): if (bool_or(get_relation_to_model(user_id, model_id) == 0, is_admin(user_id))): output("New group?") group_id = get_group_id(input()) if (group_id != ""): model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, model_id, "group"))) instantiate_link(core, "group", "", model_id, group_id) else: output("No such group!") else: output("Permission denied!") else: output("No such model!") elif (cmd == "group_create"): // Create a new group and become its owner String group_id String name output("Which group do you want to create?") name = input() group_id = get_group_id(name) if (group_id == ""): group_id = instantiate_node(core, "Group", "") instantiate_attribute(core, group_id, "name", name) instantiate_link(core, "belongsTo", "", user_id, group_id) instantiate_link(core, "owner", "", group_id, user_id) output("Group created!") else: output("Group already exists") elif (cmd == "group_delete"): // Delete an existing group String group_id String name output("Which group do you want to delete?") name = input() group_id = get_group_id(name) if (group_id != ""): if (allow_group_modify(user_id, group_id)): model_delete_element(core, group_id) else: output("Permission denied") else: output("No such group") elif (cmd == "group_owner_add"): // Add an owner to your group String group_id String other_user_id output("Which group do you want to add an owner to?") group_id = get_group_id(input()) if (group_id != ""): if (allow_group_modify(user_id, group_id)): output("Which user do you want to make an owner?") other_user_id = get_user_id(input()) 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) output("New owner added to group!") else: output("User is already an owner!") else: output("No such user") else: output("Permission denied!") else: output("No such group") elif (cmd == "group_owner_delete"): // Remove an owner from your group String group_id String other_user_id output("Which group do you want to disown someone from?") group_id = get_group_id(input()) if (group_id != ""): if (allow_group_modify(user_id, group_id)): output("Which user do you want to disown?") other_user_id = get_user_id(input()) 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)) output("Disowned group from user!") else: output("User is not even an owner of the group!") else: output("User is not even a member of the group!") else: output("No such user") else: output("Permission denied!") else: output("No such group") elif (cmd == "group_join"): // Add someone to your group String group_id String other_user_id output("Which group do you want to add someone to?") group_id = get_group_id(input()) if (group_id != ""): if (allow_group_modify(user_id, group_id)): output("Which user do you want to add?") other_user_id = get_user_id(input()) 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) output("User added to the group!") else: output("User is already a member of the group!") else: output("No such user") else: output("Permission denied!") else: output("No such group") elif (cmd == "group_kick"): // Remove someone from your group String group_id String other_user_id output("Which group do you want to kick someone from?") group_id = get_group_id(input()) if (group_id != ""): if (allow_group_modify(user_id, group_id)): output("Which user do you want to kick?") other_user_id = get_user_id(input()) 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)) output("User kicked!") else: output("User is not even a member of the group!") else: output("No such user") else: output("Permission denied!") else: output("No such group") elif (cmd == "group_list"): // List all groups you are a member of (and whether you are admin or not!) Element groups String group_id String admin 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 = " " output(string_join(admin, read_attribute(core, group_id, "name"))) 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 == "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 !