core_algorithm.alc 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242
  1. include "modelling.alh"
  2. include "library.alh"
  3. include "primitives.alh"
  4. include "constructors.alh"
  5. include "object_operations.alh"
  6. include "mini_modify.alh"
  7. include "model_management.alh"
  8. include "ramify.alh"
  9. include "conformance_scd.alh"
  10. include "transform.alh"
  11. include "metamodels.alh"
  12. Element core = ?
  13. String scd_location = "models/SimpleClassDiagrams"
  14. String core_location = "models/CoreFormalism"
  15. String core_tm_location = "models/CoreFormalism_TypeMapping"
  16. String core_model_location = "models/core"
  17. String core_model_tm_location = "models/core_TypeMapping"
  18. Void function main():
  19. // Initialize the Core Formalism
  20. String core_model
  21. String core_formalism_model
  22. String scd_model
  23. String admin_group
  24. String admin_user
  25. String nobody_group
  26. String instance_of
  27. Element scd
  28. scd = initialize_SCD(scd_location)
  29. // Create the Model itself and make public
  30. core = instantiate_model(import_node(core_location))
  31. export_node(core_model_location, core["model"])
  32. export_node(core_model_tm_location, core["type_mapping"])
  33. // Switch all new users to the user_function
  34. // This accesses the bootstrap level, so do not change this unless you know what you are doing
  35. Element root
  36. Element prev
  37. root = read_root()
  38. root = root["__hierarchy"]["__IP"]
  39. while (value_neq(root, !call)):
  40. prev = root
  41. root = root["next"]
  42. dict_delete(prev, "next")
  43. dict_add(prev, "next", user_function["body"])
  44. // Create admin group
  45. admin_group = instantiate_node(core, "Group", "")
  46. instantiate_attribute(core, admin_group, "name", "admin")
  47. // Create nobody group
  48. nobody_group = instantiate_node(core, "Group", "")
  49. instantiate_attribute(core, nobody_group, "name", "nobody")
  50. // Create admin user
  51. admin_user = instantiate_node(core, "User", "")
  52. output("Desired username for admin user?")
  53. instantiate_attribute(core, admin_user, "name", input())
  54. instantiate_attribute(core, admin_user, "admin", True)
  55. String password
  56. while (True):
  57. output("Desired password for admin user?")
  58. password = hash(input())
  59. output("Please repeat the password")
  60. if (password == hash(input())):
  61. output("Passwords match!")
  62. instantiate_attribute(core, admin_user, "password", password)
  63. break!
  64. else:
  65. output("Not the same password, please try again!")
  66. // Create link between admin user and group
  67. instantiate_link(core, "ownedBy", "", admin_group, admin_user)
  68. instantiate_link(core, "belongsTo", "", admin_user, admin_group)
  69. // Add the SimpleClassDiagrams formalism already
  70. scd_model = instantiate_node(core, "Model", "")
  71. instantiate_attribute(core, scd_model, "name", "SimpleClassDiagrams")
  72. instantiate_attribute(core, scd_model, "location", scd_location)
  73. instantiate_attribute(core, scd_model, "permissions", "221")
  74. instance_of = instantiate_link(core, "instanceOf", "", scd_model, scd_model)
  75. instantiate_attribute(core, instance_of, "type_mapping", scd["type_mapping"])
  76. // Make necessary links for the formalism to the owners
  77. instantiate_link(core, "group", "", scd_model, admin_group)
  78. instantiate_link(core, "owner", "", scd_model, admin_user)
  79. // Add the core formalism already
  80. core_formalism_model = instantiate_node(core, "Model", "")
  81. instantiate_attribute(core, core_formalism_model, "name", "CoreFormalism")
  82. instantiate_attribute(core, core_formalism_model, "location", core_location)
  83. instantiate_attribute(core, core_formalism_model, "permissions", "221")
  84. instance_of = instantiate_link(core, "instanceOf", "", core_formalism_model, scd_model)
  85. instantiate_attribute(core, instance_of, "type_mapping", ???)
  86. // Make necessary links for the formalism to the owners
  87. instantiate_link(core, "group", "", core_formalism_model, admin_group)
  88. instantiate_link(core, "owner", "", core_formalism_model, admin_user)
  89. // Add the core model
  90. core_model = instantiate_node(core, "Model", "")
  91. instantiate_attribute(core, core_model, "name", "core")
  92. instantiate_attribute(core, core_model, "location", core_model_location)
  93. instantiate_attribute(core, core_model, "permissions", "200")
  94. instance_of = instantiate_link(core, "instanceOf", "", core_model, core_formalism_model)
  95. instantiate_attribute(core, instance_of, "type_mapping", core["type_mapping"])
  96. // Make necessary links for the formalism to the owners
  97. instantiate_link(core, "group", "", core_model, admin_group)
  98. instantiate_link(core, "owner", "", core_model, admin_user)
  99. // Call this for ourselves as well
  100. log("MvC is ready!")
  101. user_function_skip_init(admin_user)
  102. // Done, so finish up
  103. // Admin user will have been deleted by the user_function as usual
  104. // Note that if there are no admin users left, it will be very difficult to manage, as nobody will have admin permissions!
  105. return !
  106. Void function get_full_model(model_id : String):
  107. Element m
  108. Element all_links
  109. String choice
  110. m = create_node()
  111. all_links = allOutgoingAssociations(core, model_id, "instanceOf")
  112. if (read_nr_out(all_links) != 1):
  113. log("WARNING: multiple instanceOf relations were detected for this model; picking one at random!")
  114. choice = set_pop(allOutgoingAssociations(core, model_id, "instanceOf"))
  115. dict_add(m, "model", import_node(read_attribute(core, model_id, "location")))
  116. dict_add(m, "type_mapping", read_attribute(core, choice, "type_mapping"))
  117. dict_add(m, "metamodel", import_node(read_attribute(core, choice, "location")))
  118. return m!
  119. Integer function get_relation_to_model(user_id : String, model_id : String):
  120. if (set_in(allAssociationDestinations(core, model_id, "owner"), user_id)):
  121. // We are the owner
  122. return 0!
  123. else:
  124. String group_id
  125. group_id = set_pop(allAssociationDestinations(core, model_id, "group"))
  126. if (set_in(allAssociationDestinations(core, user_id, "belongsTo"), group_id)):
  127. // We are in the owning group
  128. return 1!
  129. else:
  130. // We are not related whatsoever
  131. return 2!
  132. Boolean function is_admin(user_id : String):
  133. if (read_attribute(core, user_id, "admin")):
  134. return True!
  135. else:
  136. return False!
  137. Boolean function allow_read(user_id : String, model_id : String):
  138. if (is_admin(user_id)):
  139. // Is admin, so always allow
  140. return True!
  141. else:
  142. // Check permissions
  143. String permission
  144. permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id))
  145. if (bool_or(permission == "1", permission == "2")):
  146. return True!
  147. else:
  148. return False!
  149. Boolean function allow_write(user_id : String, model_id : String):
  150. if (is_admin(user_id)):
  151. // Is admin, so always allow
  152. return True!
  153. else:
  154. // Check permissions
  155. String permission
  156. permission = string_get(read_attribute(core, model_id, "permissions"), get_relation_to_model(user_id, model_id))
  157. if (permission == "2"):
  158. return True!
  159. else:
  160. return False!
  161. Boolean function allow_change_metadata(user_id : String, model_id : String):
  162. if (is_admin(user_id)):
  163. // Is admin, so always allow
  164. return True!
  165. else:
  166. if (get_relation_to_model(user_id, model_id) == 0):
  167. // Only owner can chmod
  168. return True!
  169. else:
  170. return False!
  171. Boolean function allow_group_modify(user_id : String, group_id : String):
  172. if (is_admin(user_id)):
  173. // Is admin, so always allow
  174. return True!
  175. else:
  176. if (read_nr_out(set_overlap(allIncomingAssociationInstances(core, user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))) > 0):
  177. // We are an owner
  178. return True!
  179. else:
  180. return False!
  181. Boolean function check_login(user_id : String):
  182. String password
  183. String stored_password
  184. stored_password = read_attribute(core, user_id, "password")
  185. output("Password for existing user?")
  186. password = hash(input())
  187. return password == stored_password!
  188. Element function extract_ftg(user_id : String):
  189. // Extract your personal FTG, showing only the readable models that can be opened
  190. // This function does the actual projection of transformations
  191. // TODO: Only keep transformations satisfying some properties!
  192. return create_node()!
  193. Element function user_function():
  194. String username
  195. String user_id
  196. String password
  197. // Load in all global variables, as this code is hotloaded!
  198. Element root
  199. root = read_root()
  200. root = root["__hierarchy"]["objects"]
  201. exec(root["bootstrap/modelling.alc"]["initializers"])
  202. exec(root["bootstrap/library.alc"]["initializers"])
  203. exec(root["bootstrap/constructors.alc"]["initializers"])
  204. exec(root["bootstrap/object_operations.alc"]["initializers"])
  205. exec(root["core/mini_modify.alc"]["initializers"])
  206. exec(root["bootstrap/model_management.alc"]["initializers"])
  207. exec(root["bootstrap/ramify.alc"]["initializers"])
  208. exec(root["bootstrap/transform.alc"]["initializers"])
  209. exec(root["bootstrap/conformance_scd.alc"]["initializers"])
  210. exec(root["core/core_algorithm.alc"]["initializers"])
  211. // Load in a hard-reference to the previously created model
  212. core = create_node()
  213. dict_add(core, "model", import_node(core_model_location))
  214. dict_add(core, "metamodel", import_node(scd_location))
  215. dict_add(core, "type_mapping", import_node(core_model_tm_location))
  216. output("Log on as which user?")
  217. username = input()
  218. user_id = get_user_id(username)
  219. if (user_id == ""):
  220. // New user
  221. // Add user to Core Formalism
  222. user_id = instantiate_node(core, "User", "")
  223. instantiate_attribute(core, user_id, "name", username)
  224. instantiate_attribute(core, user_id, "admin", False)
  225. while (True):
  226. output("This is a new user: please give password!")
  227. password = hash(input())
  228. output("Please repeat the password")
  229. if (password == hash(input())):
  230. output("Passwords match!")
  231. output("User created")
  232. instantiate_attribute(core, user_id, "password", password)
  233. break!
  234. else:
  235. output("Not the same password, please try again!")
  236. // Now call with user created
  237. user_function_skip_init(user_id)
  238. else:
  239. while (bool_not(check_login(user_id))):
  240. output("Wrong password! Try again")
  241. user_function_skip_init(user_id)
  242. // User destroyed already, so just stop execution
  243. // TODO return a fresh node as otherwise the compiler doesn't take this
  244. return create_node()!
  245. String function get_model_id(name : String):
  246. Element models
  247. String model
  248. models = allInstances(core, "Model")
  249. while (read_nr_out(models) > 0):
  250. model = set_pop(models)
  251. if (value_eq(name, read_attribute(core, model, "name"))):
  252. return model!
  253. return ""!
  254. String function get_user_id(name : String):
  255. Element users
  256. String user
  257. users = allInstances(core, "User")
  258. while (read_nr_out(users) > 0):
  259. user = set_pop(users)
  260. if (value_eq(read_attribute(core, user, "name"), name)):
  261. return user!
  262. return ""!
  263. String function get_group_id(name : String):
  264. Element groups
  265. String group
  266. groups = allInstances(core, "Group")
  267. while (read_nr_out(groups) > 0):
  268. group = set_pop(groups)
  269. if (value_eq(read_attribute(core, group, "name"), name)):
  270. return group!
  271. return ""!
  272. Void function model_create(model : Element, name : String, user_id : String, type_id : String, kind : String):
  273. String location
  274. String model_id
  275. String instance_of
  276. location = "/models/" + cast_id2s(model)
  277. export_node(location, model["model"])
  278. // Manage meta-info
  279. model_id = instantiate_node(core, kind, "")
  280. instantiate_attribute(core, model_id, "name", name)
  281. instantiate_attribute(core, model_id, "location", location)
  282. instantiate_attribute(core, model_id, "permissions", "200")
  283. instantiate_link(core, "owner", "", model_id, user_id)
  284. instantiate_link(core, "group", "", model_id, get_group_id("nobody"))
  285. instance_of = instantiate_link(core, "instanceOf", "", model_id, type_id)
  286. instantiate_attribute(core, instance_of, "type_mapping", model["type_mapping"])
  287. return!
  288. Void function model_overwrite(model : Element, model_id : String):
  289. String location
  290. location = "/models/" + cast_id2s(model)
  291. export_node(location, model["model"])
  292. // Change location in meta-data
  293. unset_attribute(core, model_id, "location")
  294. instantiate_attribute(core, model_id, "location", location)
  295. return!
  296. Boolean function check_is_typed_by(model_id : String, metamodel_id : String):
  297. // TODO check if there is actually an instanceOf link between them
  298. // --> quick check!
  299. return True!
  300. Boolean function check_conformance(model_id : String):
  301. // TODO check if it actually conforms, considering that instanceOf link
  302. // --> in-depth check
  303. return True!
  304. Void function user_function_skip_init(user_id : String):
  305. String cmd
  306. output("Welcome to the Model Management Interface v2.0!")
  307. output("Use the 'help' command for a list of possible commands")
  308. while (True):
  309. output("Ready for command...")
  310. cmd = input()
  311. if (cmd == "help"):
  312. output("Model operations")
  313. output(" model_add -- Add a new model")
  314. output(" model_modify -- Modify an existing model")
  315. output(" model_delete -- [TODO] Delete a model and all related transformations")
  316. output(" model_list -- List all models")
  317. output(" model_list_full -- List all models with full info")
  318. output(" model_overwrite -- Overwrites a model with an uploaded model, leaving all metadata")
  319. output("")
  320. output("Transformation-specific operations")
  321. output(" transformation_add_MT_language -- Create a RAMified metamodel of a set of models")
  322. output(" transformation_add_MT -- Initialize a new model transformation")
  323. output(" transformation_add_AL -- [TODO] Initialize a new action language transformation")
  324. output(" transformation_add_EXT -- [TODO] Initialize a new external tool transformation")
  325. output(" transformation_add_MANUAL -- [TODO] Initialize a new manual transformation")
  326. output(" transformation_execute -- Execute a transformation on a set of input models")
  327. output(" transformation_list -- List all model transformations")
  328. output(" transformation_list_full -- List all model transformations with permissions")
  329. output(" transformation_detail -- List transformation details")
  330. output(" transformation_RAMify -- RAMify a metamodel (again)")
  331. output("")
  332. output("Model permission operations")
  333. output(" permission_modify -- Change model permissions")
  334. output(" permission_owner -- Change model owner")
  335. output(" permission_group -- Change model group")
  336. output("")
  337. output("Group operations")
  338. output(" group_create -- Create a group")
  339. output(" group_delete -- Delete a group")
  340. output(" group_owner_add -- Add group owner")
  341. output(" group_owner_delete -- Remove group owner")
  342. output(" group_join -- Add someone to your group")
  343. output(" group_kick -- Kick someone from your group")
  344. output(" group_list -- List all groups you are a member of")
  345. output("")
  346. output("Admin operations")
  347. output(" admin_promote -- Promote a user to admin status")
  348. output(" admin_demote -- Demote a user to normal status")
  349. output("")
  350. output("General operations")
  351. output(" self-destruct -- Remove current user and revoke all permissions ")
  352. output(" exit -- Kill the current task, while retaining user")
  353. elif (cmd == "model_add"):
  354. // Model addition operation, which uses model upload commands of the compiler
  355. String name
  356. String type
  357. String location
  358. String type_id
  359. Element new_model
  360. String new_model_id
  361. output("Creating new model!")
  362. output("Model type?")
  363. type_id = get_model_id(input())
  364. if (type_id != ""):
  365. // Type exists
  366. if (allow_read(user_id, type_id)):
  367. // And is readable
  368. output("Model name?")
  369. name = input()
  370. if (get_model_id(name) == ""):
  371. // Model doesn't exist yet
  372. output("Waiting for model constructors...")
  373. m = get_full_model(type_id)
  374. new_model = construct_model_raw(m)
  375. model_create(new_model, name, user_id, type_id, "Model")
  376. output("Model upload success!")
  377. else:
  378. output("Model with that name already exists!")
  379. else:
  380. output("Permission denied")
  381. else:
  382. output("Could not find type model!")
  383. elif (cmd == "transformation_execute"):
  384. // Execute a transformation, whatever type it is
  385. // First we detect the type, so we know how to prepare for invocation
  386. String transformation_id
  387. String exact_type
  388. Element sources
  389. Element targets
  390. String source
  391. String target
  392. String name_id
  393. Element inputs
  394. Element outputs
  395. Element trace_links
  396. String target_model_name
  397. String source_model_name
  398. output("Which transformation do you want to execute?")
  399. transformation_id = get_model_id(input())
  400. if (transformation_id != ""):
  401. if (allow_read(user_id, transformation_id)):
  402. if (is_nominal_instance(core, transformation_id, "Transformation")):
  403. // Read out source and target links
  404. sources = allOutgoingAssociationInstances(core, transformation_id, "transformInput")
  405. inputs = create_node()
  406. while (read_nr_out(sources) > 0):
  407. source = set_pop(sources)
  408. output(string_join("Which model to bind for source element ", read_attribute(core, source, "name")))
  409. source_model_name = input()
  410. name_id = get_model_id(source_model_name)
  411. if (name_id != ""):
  412. if (allow_read(user_id, name_id)):
  413. // Check for conformance to the specified metamodel!
  414. Element specified_model
  415. // TODO Maybe find out which conformance relation to use, as there might be multiple!
  416. if (check_is_typed_by(name_id, source)):
  417. if (check_conformance(name_id)):
  418. dict_add(inputs, read_attribute(core, source, "name"), source_model_name)
  419. else:
  420. output("Model has correct type but does not conform completely!")
  421. set_add(sources, source)
  422. else:
  423. output("Model has different type!")
  424. set_add(sources, source)
  425. else:
  426. output("Permission denied")
  427. set_add(sources, source)
  428. else:
  429. output("No such model")
  430. set_add(sources, source)
  431. targets = allOutgoingAssociationInstances(core, transformation_id, "transformOutput")
  432. outputs = create_node()
  433. while (read_nr_out(targets) > 0):
  434. target = set_pop(targets)
  435. output(string_join("Which model to create for target element ", read_attribute(core, target, "name")))
  436. target_model_name = input()
  437. if (get_model_id(target_model_name) == ""):
  438. // Doesn't exist yet, so we can easily create
  439. dict_add(outputs, read_attribute(core, target, "name"), target_model_name)
  440. else:
  441. // Already exists, so we need to check for write access
  442. if (allow_write(user_id, get_model_id(target_model_name))):
  443. dict_add(outputs, read_attribute(core, target, "name"), target_model_name)
  444. else:
  445. output("Permission denied; try again")
  446. exact_type = read_type(core, transformation_id)
  447. if (exact_type == "ModelTransformation"):
  448. // Model transformation is always in-place and uses only a single metamodel
  449. // Therefore, we must:
  450. // 1) Create an empty model, instance of merged metamodel
  451. // 2) Merge the different source models and retype
  452. // 3) Perform the transformation on the merged model
  453. // 4) Split the resulting model based on the target formalisms
  454. //
  455. // There is one exception: if the target model is bound to a source model, that model is overwritten
  456. // This allows for some optimizations when it is a simple in-place transformation (skip model copy, join, and split)
  457. // First check for this exception, as it is much faster
  458. Element input_model
  459. Element schedule_model
  460. String trace_link_id
  461. Element merged_model
  462. String merged_metamodel_id
  463. String ramified_metamodel_id
  464. Boolean result
  465. schedule_model = get_full_model(transformation_id)
  466. // Need to fall back to the default approach, which is way slower
  467. // 1) Create empty instance of merged metamodel
  468. ramified_metamodel_id = set_pop(followAssociation(core, transformation_id, "instanceOf"))
  469. trace_links = allOutgoingAssociationInstances(core, ramified_metamodel_id, "tracability")
  470. merged_metamodel_id = ""
  471. while (read_nr_out(trace_links) > 0):
  472. trace_link_id = set_pop(trace_links)
  473. if (value_eq(read_attribute(core, trace_link_id, "type"), "RAMified")):
  474. merged_metamodel_id = readAssociationDestination(core, trace_link_id)
  475. if (merged_metamodel_id != ""):
  476. merged_model = instantiate_model(get_full_model(merged_metamodel_id))
  477. // 2) Merge source models
  478. String key
  479. Element keys
  480. Element input_keys
  481. Element output_keys
  482. input_keys = dict_keys(inputs)
  483. while (read_nr_out(input_keys) > 0):
  484. key = set_pop(input_keys)
  485. model_join(merged_model, get_full_model(get_model_id(inputs[key])), key + "/")
  486. // 3) Transform
  487. result = transform(merged_model, schedule_model)
  488. output("Transformation executed with result: " + cast_v2s(result))
  489. // 4) Split in different files depending on type
  490. String desired_metamodel_id
  491. Element split_off_model
  492. output_keys = dict_keys(outputs)
  493. while (read_nr_out(output_keys) > 0):
  494. key = set_pop(output_keys)
  495. desired_metamodel_id = get_model_id(key)
  496. split_off_model = model_split(merged_model, get_full_model(desired_metamodel_id), key + "/")
  497. // Check if the destination model already exists
  498. if (get_model_id(outputs[key]) == ""):
  499. // New model
  500. model_create(split_off_model, outputs[key], user_id, desired_metamodel_id, "Model")
  501. else:
  502. // Model exists, so we overwrite
  503. model_overwrite(split_off_model, get_model_id(outputs[key]))
  504. else:
  505. output("Could not resolve intermediate merged metamodel")
  506. elif (exact_type == "ActionLanguage"):
  507. output("Not Implemented yet!")
  508. else:
  509. output("Did not know how to interpret model of type " + exact_type)
  510. else:
  511. output("Model is not an executable transformation")
  512. else:
  513. output("Permission denied")
  514. else:
  515. output("No such transformation")
  516. elif (cmd == "model_overwrite"):
  517. // Overwrites an existing model without changing any metadata
  518. String model_id
  519. Element new_model
  520. output("Which model to overwrite?")
  521. model_id = get_model_id(input())
  522. if (model_id != ""):
  523. if (allow_write(user_id, model_id)):
  524. if (allow_read(user_id, set_pop(followAssociation(core, model_id, "instanceOf")))):
  525. output("Waiting for model constructors...")
  526. new_model = construct_model_raw(get_full_model(set_pop(followAssociation(core, model_id, "instanceOf"))))
  527. model_overwrite(new_model, model_id)
  528. output("Model overwrite success!")
  529. else:
  530. output("Permission denied")
  531. else:
  532. output("Permission denied")
  533. else:
  534. output("No such model")
  535. elif (cmd == "model_modify"):
  536. // Model modify operation, which uses the mini_modify.alc operations, though with extensions for access control
  537. String model_id
  538. String type_id
  539. output("Which model do you want to modify?")
  540. model_id = get_model_id(input())
  541. if (model_id != ""):
  542. if (allow_read(user_id, model_id)):
  543. type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
  544. if (allow_read(user_id, type_id)):
  545. modify(get_full_model(model_id), allow_write(user_id, model_id))
  546. else:
  547. output("Permission denied")
  548. else:
  549. output("Permission denied")
  550. else:
  551. output("Could not find model!")
  552. elif (cmd == "model_delete"):
  553. // Delete a model and all of its related transformations
  554. String model_id
  555. output("=================================================")
  556. output("WARNING: Deletion is a very destructive operation")
  557. output(" as it also deletes all transformations ")
  558. output(" defined which make use of this model! ")
  559. output("=================================================")
  560. output("")
  561. output("Currently not supported!")
  562. elif (cmd == "model_list"):
  563. // List all models
  564. Element models
  565. String m
  566. models = allInstances(core, "Model")
  567. while (read_nr_out(models) > 0):
  568. m = set_pop(models)
  569. log("Read attribute name of " + cast_e2s(m))
  570. output(string_join((string_join(" ", read_attribute(core, m, "name")) + " : "), read_attribute(core, set_pop(followAssociation(core, m, "instanceOf")), "name")))
  571. elif (cmd == "model_list_full"):
  572. // List all models with full info
  573. Element models
  574. String m
  575. String permissions
  576. String owner
  577. String group
  578. String name
  579. String type
  580. models = allInstances(core, "Model")
  581. while (read_nr_out(models) > 0):
  582. m = set_pop(models)
  583. permissions = read_attribute(core, m, "permissions")
  584. owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
  585. group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
  586. name = read_attribute(core, m, "name")
  587. type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")
  588. output(((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + name) + " : ") + type)
  589. elif (cmd == "transformation_add_MT_language"):
  590. // Create a model transformation language from a set of input and output formalisms
  591. String name
  592. String model_id
  593. Element source
  594. Element target
  595. Element all_formalisms
  596. Element merged_formalism
  597. Element ramified_formalism
  598. String old_type_id
  599. String type_id
  600. String location
  601. String new_model_id
  602. old_type_id = ""
  603. // Read involved formalisms
  604. all_formalisms = create_node()
  605. output("Formalisms to include (terminate with empty string)?")
  606. name = input()
  607. while (name != ""):
  608. model_id = get_model_id(name)
  609. if (model_id != ""):
  610. if (allow_read(user_id, model_id)):
  611. type_id = set_pop(allAssociationDestinations(core, model_id, "instanceOf"))
  612. if (bool_or(old_type_id == "", type_id == old_type_id)):
  613. set_add(all_formalisms, create_tuple(name, get_full_model(model_id)))
  614. old_type_id = type_id
  615. elif (old_type_id != type_id):
  616. // Already have a previous type_id and now another: CLASH
  617. output("Cannot add model as types not compatible with previous models; try again")
  618. else:
  619. output("Model not readable; try again")
  620. else:
  621. output("No such model; try again")
  622. name = input()
  623. // Merge both into a single metamodel
  624. if (read_nr_out(all_formalisms) > 0):
  625. output("Name of the RAMified transformation metamodel?")
  626. name = input()
  627. if (get_model_id(name) == ""):
  628. String merged_formalism_id
  629. String ramified_formalism_id
  630. String source_formalism_id
  631. String tracability_link
  632. // New location is available, so write
  633. merged_formalism = model_fuse(set_copy(all_formalisms))
  634. model_create(merged_formalism, "__merged_" + name, user_id, type_id, "Model")
  635. merged_formalism_id = get_model_id("__merged_" + name)
  636. // Add tracability links at this level
  637. while (read_nr_out(all_formalisms) > 0):
  638. source_formalism_id = get_model_id(list_read(set_pop(all_formalisms), 0))
  639. tracability_link = instantiate_link(core, "tracability", "", merged_formalism_id, source_formalism_id)
  640. instantiate_attribute(core, tracability_link, "type", "merged")
  641. // Merge complete, now RAMify!
  642. ramified_formalism = ramify(merged_formalism)
  643. model_create(ramified_formalism, name, user_id, type_id, "Model")
  644. ramified_formalism_id = get_model_id(name)
  645. // Add tracability link at this level
  646. tracability_link = instantiate_link(core, "tracability", "", ramified_formalism_id, merged_formalism_id)
  647. instantiate_attribute(core, tracability_link, "type", "RAMified")
  648. else:
  649. output("Model already exists!")
  650. else:
  651. output("At least one formalism is required")
  652. elif (cmd == "transformation_RAMify"):
  653. // RAMify a metamodel
  654. String merged_model_id
  655. String target_model_name
  656. String target_model_id
  657. Element target_model
  658. String tracability_link
  659. output("Which metamodel do you want to RAMify?")
  660. merged_model_id = get_model_id(input())
  661. if (merged_model_id != ""):
  662. if (allow_read(user_id, merged_model_id)):
  663. output("Where do you want to store the RAMified metamodel?")
  664. target_model_name = input()
  665. target_model_id = get_model_id(target_model_name)
  666. if (target_model_id == ""):
  667. // New model, so everything is fine
  668. target_model = ramify(get_full_model(merged_model_id))
  669. model_create(target_model, target_model_name, user_id, set_pop(allAssociationDestinations(core, merged_model_id, "instanceOf")), "Model")
  670. target_model_id = get_model_id(target_model_name)
  671. tracability_link = instantiate_link(core, "tracability", "", target_model_id, merged_model_id)
  672. instantiate_attribute(core, tracability_link, "type", "RAMified")
  673. else:
  674. // Existing model, so overwrite
  675. if (allow_write(user_id, target_model_id)):
  676. target_model = ramify(get_full_model(merged_model_id))
  677. model_overwrite(target_model, target_model_id)
  678. model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, target_model_id, "tracability")))
  679. tracability_link = instantiate_link(core, "tracability", "", target_model_id, merged_model_id)
  680. instantiate_attribute(core, tracability_link, "type", "RAMified")
  681. else:
  682. output("Permission denied")
  683. else:
  684. output("Permission denied!")
  685. else:
  686. output("No such model")
  687. elif (cmd == "transformation_add_MT"):
  688. // Add a model transformation model
  689. // Just a usual model instantiation, but need to add the source and target links based on user info
  690. String ramified_metamodel_id
  691. String model_id
  692. Element models
  693. Element links
  694. String link_id
  695. Element supported
  696. Element source
  697. Element target
  698. String name
  699. String new_model_id
  700. String merged_link_id
  701. Element links_merged
  702. String merged_metamodel_id
  703. source = create_node()
  704. target = create_node()
  705. supported = create_node()
  706. output("RAMified metamodel to use?")
  707. ramified_metamodel_id = get_model_id(input())
  708. if (ramified_metamodel_id != ""):
  709. if (allow_read(user_id, ramified_metamodel_id)):
  710. output("Supported metamodels:")
  711. links = allOutgoingAssociationInstances(core, ramified_metamodel_id, "tracability")
  712. while (read_nr_out(links) > 0):
  713. link_id = set_pop(links)
  714. merged_metamodel_id = readAssociationDestination(core, link_id)
  715. if (value_eq(read_attribute(core, link_id, "type"), "RAMified")):
  716. links_merged = allOutgoingAssociationInstances(core, merged_metamodel_id, "tracability")
  717. while (read_nr_out(links_merged) > 0):
  718. merged_link_id = set_pop(links_merged)
  719. if (value_eq(read_attribute(core, merged_link_id, "type"), "merged")):
  720. output(string_join(" ", read_attribute(core, readAssociationDestination(core, merged_link_id), "name")))
  721. set_add(supported, readAssociationDestination(core, merged_link_id))
  722. output("")
  723. output("Which ones do you want to use as source (empty string to finish)?")
  724. name = input()
  725. while (name != ""):
  726. model_id = get_model_id(name)
  727. if (model_id != ""):
  728. if (set_in(supported, model_id)):
  729. if (bool_not(set_in(source, model_id))):
  730. set_add(source, model_id)
  731. output("Model added as source")
  732. else:
  733. output("Model already selected as source")
  734. else:
  735. output("Model is not supported by RAMified metamodel!")
  736. else:
  737. output("No such model; try again")
  738. name = input()
  739. output("Which ones do you want to use as target (empty string to finish)?")
  740. name = input()
  741. while (name != ""):
  742. model_id = get_model_id(name)
  743. if (model_id != ""):
  744. if (set_in(supported, model_id)):
  745. if (bool_not(set_in(target, model_id))):
  746. set_add(target, model_id)
  747. output("Model added as target")
  748. else:
  749. output("Model already selected as target")
  750. else:
  751. output("Model is not supported by RAMified metamodel!")
  752. else:
  753. output("No such model; try again")
  754. name = input()
  755. output("Name of new transformation?")
  756. name = input()
  757. if (get_model_id(name) == ""):
  758. String new_model
  759. // Finished with all information, now create the model itself!
  760. output("Waiting for model constructors...")
  761. new_model = construct_model_raw(get_full_model(ramified_metamodel_id))
  762. model_create(new_model, name, user_id, ramified_metamodel_id, "ModelTransformation")
  763. model_id = get_model_id(name)
  764. // Extend metadata with info on source and target
  765. String link
  766. String dst
  767. while (read_nr_out(source) > 0):
  768. dst = set_pop(source)
  769. link = instantiate_link(core, "transformInput", "", model_id, dst)
  770. instantiate_attribute(core, link, "name", read_attribute(core, dst, "name"))
  771. while (read_nr_out(target) > 0):
  772. dst = set_pop(target)
  773. link = instantiate_link(core, "transformOutput", "", model_id, dst)
  774. instantiate_attribute(core, link, "name", read_attribute(core, dst, "name"))
  775. else:
  776. output("Model already exists")
  777. else:
  778. output("Permission denied")
  779. else:
  780. output("No such model")
  781. elif (cmd == "transformation_list"):
  782. // List all models
  783. Element models
  784. String m
  785. String type
  786. models = allInstances(core, "Transformation")
  787. while (read_nr_out(models) > 0):
  788. m = set_pop(models)
  789. 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"))))
  790. elif (cmd == "transformation_list_full"):
  791. // List all models with full info
  792. Element models
  793. String m
  794. String permissions
  795. String owner
  796. String group
  797. String name
  798. String type
  799. models = allInstances(core, "Transformation")
  800. while (read_nr_out(models) > 0):
  801. m = set_pop(models)
  802. permissions = read_attribute(core, m, "permissions")
  803. owner = read_attribute(core, set_pop(allAssociationDestinations(core, m, "owner")), "name")
  804. group = read_attribute(core, set_pop(allAssociationDestinations(core, m, "group")), "name")
  805. name = read_attribute(core, m, "name")
  806. type = read_attribute(core, set_pop(allAssociationDestinations(core, m, "instanceOf")), "name")
  807. output(((((((((" " + permissions) + " ") + owner) + " ") + group) + " ") + ((("[" + read_type(core, m)) + "] ") + name)) + " : ") + type)
  808. elif (cmd == "permission_modify"):
  809. String permissions
  810. Integer permission
  811. String model_id
  812. output("Which model do you want to change permissions of?")
  813. model_id = get_model_id(input())
  814. if (model_id != ""):
  815. if (get_relation_to_model(user_id, model_id) == 0):
  816. output("New permissions?")
  817. permissions = input()
  818. Boolean fail
  819. Integer i
  820. i = 0
  821. if (string_len(permissions) != 3):
  822. fail = True
  823. while (i < 3):
  824. permission = cast_s2i(string_get(permissions, i))
  825. if (bool_or(permission < 0, permission > 2)):
  826. fail = True
  827. break!
  828. i = i + 1
  829. if (bool_not(fail)):
  830. unset_attribute(core, model_id, "permissions")
  831. instantiate_attribute(core, model_id, "permissions", permissions)
  832. else:
  833. output("Permissions must be a string of three characters with each character being a digit between 0 and 2")
  834. else:
  835. output("Permission denied!")
  836. else:
  837. output("No such model!")
  838. elif (cmd == "permission_owner"):
  839. String permissions
  840. String model_id
  841. String user_id
  842. output("Which model do you want to change owner of?")
  843. model_id = get_model_id(input())
  844. if (model_id != ""):
  845. if (bool_or(get_relation_to_model(user_id, model_id) == 0, is_admin(user_id))):
  846. output("New owner?")
  847. user_id = get_user_id(input())
  848. if (user_id != ""):
  849. model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, model_id, "owner")))
  850. instantiate_link(core, "owner", "", model_id, user_id)
  851. else:
  852. output("No such user!")
  853. else:
  854. output("Permission denied!")
  855. else:
  856. output("No such model!")
  857. elif (cmd == "permission_group"):
  858. String permissions
  859. String model_id
  860. String group_id
  861. output("Which model do you want to change permissions of?")
  862. model_id = get_model_id(input())
  863. if (model_id != ""):
  864. if (bool_or(get_relation_to_model(user_id, model_id) == 0, is_admin(user_id))):
  865. output("New group?")
  866. group_id = get_group_id(input())
  867. if (group_id != ""):
  868. model_delete_element(core, set_pop(allOutgoingAssociationInstances(core, model_id, "group")))
  869. instantiate_link(core, "group", "", model_id, group_id)
  870. else:
  871. output("No such group!")
  872. else:
  873. output("Permission denied!")
  874. else:
  875. output("No such model!")
  876. elif (cmd == "group_create"):
  877. // Create a new group and become its owner
  878. String group_id
  879. String name
  880. output("Which group do you want to create?")
  881. name = input()
  882. group_id = get_group_id(name)
  883. if (group_id == ""):
  884. group_id = instantiate_node(core, "Group", "")
  885. instantiate_attribute(core, group_id, "name", name)
  886. instantiate_link(core, "belongsTo", "", user_id, group_id)
  887. instantiate_link(core, "owner", "", group_id, user_id)
  888. output("Group created!")
  889. else:
  890. output("Group already exists")
  891. elif (cmd == "group_delete"):
  892. // Delete an existing group
  893. String group_id
  894. String name
  895. output("Which group do you want to delete?")
  896. name = input()
  897. group_id = get_group_id(name)
  898. if (group_id != ""):
  899. if (allow_group_modify(user_id, group_id)):
  900. model_delete_element(core, group_id)
  901. else:
  902. output("Permission denied")
  903. else:
  904. output("No such group")
  905. elif (cmd == "group_owner_add"):
  906. // Add an owner to your group
  907. String group_id
  908. String other_user_id
  909. output("Which group do you want to add an owner to?")
  910. group_id = get_group_id(input())
  911. if (group_id != ""):
  912. if (allow_group_modify(user_id, group_id)):
  913. output("Which user do you want to make an owner?")
  914. other_user_id = get_user_id(input())
  915. if (other_user_id != ""):
  916. Element overlap
  917. overlap = set_overlap(allIncomingAssociationInstances(core, other_user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))
  918. if (read_nr_out(overlap) == 0):
  919. instantiate_link(core, "owner", "", group_id, other_user_id)
  920. overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  921. if (read_nr_out(overlap) == 0):
  922. instantiate_link(core, "belongsTo", "", other_user_id, group_id)
  923. output("New owner added to group!")
  924. else:
  925. output("User is already an owner!")
  926. else:
  927. output("No such user")
  928. else:
  929. output("Permission denied!")
  930. else:
  931. output("No such group")
  932. elif (cmd == "group_owner_delete"):
  933. // Remove an owner from your group
  934. String group_id
  935. String other_user_id
  936. output("Which group do you want to disown someone from?")
  937. group_id = get_group_id(input())
  938. if (group_id != ""):
  939. if (allow_group_modify(user_id, group_id)):
  940. output("Which user do you want to disown?")
  941. other_user_id = get_user_id(input())
  942. if (other_user_id != ""):
  943. Element overlap
  944. overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  945. if (read_nr_out(overlap) > 0):
  946. overlap = set_overlap(allIncomingAssociationInstances(core, other_user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))
  947. if (read_nr_out(overlap) > 0):
  948. model_delete_element(core, set_pop(overlap))
  949. output("Disowned group from user!")
  950. else:
  951. output("User is not even an owner of the group!")
  952. else:
  953. output("User is not even a member of the group!")
  954. else:
  955. output("No such user")
  956. else:
  957. output("Permission denied!")
  958. else:
  959. output("No such group")
  960. elif (cmd == "group_join"):
  961. // Add someone to your group
  962. String group_id
  963. String other_user_id
  964. output("Which group do you want to add someone to?")
  965. group_id = get_group_id(input())
  966. if (group_id != ""):
  967. if (allow_group_modify(user_id, group_id)):
  968. output("Which user do you want to add?")
  969. other_user_id = get_user_id(input())
  970. if (other_user_id != ""):
  971. Element overlap
  972. overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  973. if (read_nr_out(overlap) == 0):
  974. instantiate_link(core, "belongsTo", "", other_user_id, group_id)
  975. output("User added to the group!")
  976. else:
  977. output("User is already a member of the group!")
  978. else:
  979. output("No such user")
  980. else:
  981. output("Permission denied!")
  982. else:
  983. output("No such group")
  984. elif (cmd == "group_kick"):
  985. // Remove someone from your group
  986. String group_id
  987. String other_user_id
  988. output("Which group do you want to kick someone from?")
  989. group_id = get_group_id(input())
  990. if (group_id != ""):
  991. if (allow_group_modify(user_id, group_id)):
  992. output("Which user do you want to kick?")
  993. other_user_id = get_user_id(input())
  994. if (other_user_id != ""):
  995. Element overlap
  996. overlap = set_overlap(allOutgoingAssociationInstances(core, other_user_id, "belongsTo"), allIncomingAssociationInstances(core, group_id, "belongsTo"))
  997. if (read_nr_out(overlap) > 0):
  998. model_delete_element(core, set_pop(overlap))
  999. // Check if user was an owner as well
  1000. overlap = set_overlap(allIncomingAssociationInstances(core, other_user_id, "owner"), allOutgoingAssociationInstances(core, group_id, "owner"))
  1001. if (read_nr_out(overlap) > 0):
  1002. model_delete_element(core, set_pop(overlap))
  1003. output("User kicked!")
  1004. else:
  1005. output("User is not even a member of the group!")
  1006. else:
  1007. output("No such user")
  1008. else:
  1009. output("Permission denied!")
  1010. else:
  1011. output("No such group")
  1012. elif (cmd == "group_list"):
  1013. // List all groups you are a member of (and whether you are admin or not!)
  1014. Element groups
  1015. String group_id
  1016. String admin
  1017. groups = allAssociationDestinations(core, user_id, "belongsTo")
  1018. while (read_nr_out(groups) > 0):
  1019. group_id = set_pop(groups)
  1020. if (set_in(allOutgoingAssociationInstances(core, group_id, "owner"), user_id)):
  1021. admin = " A "
  1022. else:
  1023. admin = " "
  1024. output(string_join(admin, read_attribute(core, group_id, "name")))
  1025. elif (cmd == "admin_promote"):
  1026. // Promote a user to admin status
  1027. if (is_admin(user_id)):
  1028. String other_user_id
  1029. output("Which user do you want to promote?")
  1030. other_user_id = get_user_id(input())
  1031. if (other_user_id != ""):
  1032. unset_attribute(core, other_user_id, "admin")
  1033. instantiate_attribute(core, other_user_id, "admin", True)
  1034. output("Permissions granted!")
  1035. else:
  1036. output("No such user!")
  1037. else:
  1038. output("Permission denied!")
  1039. elif (cmd == "admin_demote"):
  1040. // Demote a user to normal status
  1041. if (is_admin(user_id)):
  1042. String other_user_id
  1043. output("Which user do you want to demote?")
  1044. other_user_id = get_user_id(input())
  1045. if (other_user_id != ""):
  1046. unset_attribute(core, other_user_id, "admin")
  1047. instantiate_attribute(core, other_user_id, "admin", False)
  1048. output("Permissions revoked!")
  1049. else:
  1050. output("No such user!")
  1051. else:
  1052. output("Permission denied!")
  1053. elif (cmd == "self-destruct"):
  1054. // Delete user from Core Formalism
  1055. model_delete_element(core, user_id)
  1056. return !
  1057. elif (cmd == "exit"):
  1058. // Exit by actually removing the user and decoupling it from all of its models
  1059. // Restarting with the same user name will NOT grant you access to anything of the previous user with that same name
  1060. // as the current user will have been deleted
  1061. return !
  1062. else:
  1063. output("Unknown command: " + cmd)
  1064. // We never get here!
  1065. return !