modelverse.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. from sccd.runtime.statecharts_core import Event
  2. import sccd.runtime.socket2event as socket2event
  3. import modelverse_SCCD
  4. import time
  5. controller = modelverse_SCCD.Controller()
  6. socket2event.boot_translation_service(controller)
  7. ID = 0
  8. # Exceptions
  9. class ModelverseException(Exception):
  10. pass
  11. class UnknownError(ModelverseException):
  12. pass
  13. class UnknownIdentifier(ModelverseException):
  14. pass
  15. class CompilationError(ModelverseException):
  16. pass
  17. class NoSuchAttribute(ModelverseException):
  18. pass
  19. class UnknownModel(ModelverseException):
  20. pass
  21. class ConnectionError(ModelverseException):
  22. pass
  23. class ModelExists(ModelverseException):
  24. pass
  25. class PermissionDenied(ModelverseException):
  26. pass
  27. class InvalidMode(ModelverseException):
  28. pass
  29. class InterfaceMismatch(ModelverseException):
  30. pass
  31. class UnknownMetamodellingHierarchy(ModelverseException):
  32. pass
  33. def run_controller():
  34. try:
  35. controller.start()
  36. finally:
  37. controller.stop()
  38. def _next_ID():
  39. global ID
  40. ID += 1
  41. return ID
  42. def INPUT(action, context, parameters):
  43. print("Executing " + str(action))
  44. print("Parameters: " + str(parameters))
  45. print("In context: " + str(context))
  46. controller.addInput(Event("action", "action_in", [action, _next_ID(), context, parameters]))
  47. def OUTPUT():
  48. response = responses.fetch(-1)
  49. print("Got response with name: " + str(response.name))
  50. if response.name == "result":
  51. print("Value: " + str(response.parameters[1]))
  52. return response.parameters[1]
  53. elif response.name == "exception":
  54. print("Exception: " + str(response.parameters))
  55. if response.parameters[1] == "UnknownIdentifier":
  56. raise UnknownIdentifier()
  57. elif response.parameters[1] == "UnknownMetamodellingHierarchy":
  58. raise UnknownMetamodellingHierarchy()
  59. def init(address_param="127.0.0.1:8001", timeout=20.0):
  60. INPUT("init", None, [address_param, timeout])
  61. return OUTPUT()
  62. def login(username, password):
  63. INPUT("login", None, [username, password])
  64. return OUTPUT()
  65. def model_list(location):
  66. INPUT("model_list", None, [location])
  67. return OUTPUT()
  68. def model_add(model_name, metamodel_name, model_code=""):
  69. INPUT("model_add", None, [model_name, metamodel_name, model_code])
  70. return OUTPUT()
  71. def model_delete(model_name):
  72. INPUT("model_delete", None, [model_name])
  73. return OUTPUT()
  74. def model_list_full(location):
  75. INPUT("model_list_full", None, [location])
  76. return OUTPUT()
  77. def verify(model_name, metamodel_name):
  78. INPUT("verify", None, [model_name, metamodel_name])
  79. return OUTPUT()
  80. def model_overwrite(model_name, new_model):
  81. INPUT("model_overwrite", None, [model_name, new_model])
  82. return OUTPUT()
  83. def disconnect():
  84. INPUT("disconnect", None, [])
  85. return OUTPUT()
  86. def user_logout():
  87. INPUT("user_logout", None, [])
  88. return OUTPUT()
  89. def user_delete():
  90. INPUT("user_delete", None, [])
  91. return OUTPUT()
  92. def model_render(model_name, mapper_name):
  93. INPUT("model_render", None, [model_name, mapper_name])
  94. return OUTPUT()
  95. def transformation_between(source, target):
  96. INPUT("transformation_between", None, [source, target])
  97. return OUTPUT()
  98. def transformation_add_MT(source_metamodels, target_metamodels, operation_name, code, callback=None):
  99. INPUT("transformation_add_MT", None, [source_metamodels, target_metamodels, operation_name, code])
  100. context = OUTPUT()
  101. if callback is not None:
  102. callback(context)
  103. print("Callback finished; sending exit")
  104. INPUT("exit", context, [])
  105. return OUTPUT()
  106. def transformation_add_AL(source_metamodels, target_metamodels, operation_name, code, callback=None):
  107. INPUT("transformation_add_AL", None, [source_metamodels, target_metamodels, operation_name, code])
  108. context = OUTPUT()
  109. if callback is not None:
  110. callback(context)
  111. INPUT("exit", context, [])
  112. return OUTPUT()
  113. def transformation_add_MANUAL(source_metamodels, target_metamodels, operation_name, callback=None):
  114. INPUT("transformation_add_MANUAL", None, [source_metamodels, target_metamodels, operation_name])
  115. context = OUTPUT()
  116. if callback is not None:
  117. print("DOING CALLBACK FOR MANUAL")
  118. callback(context)
  119. print("CALLBACK FINISHED")
  120. INPUT("exit", context, [])
  121. return OUTPUT()
  122. def transformation_execute_MT(operation_name, input_models_dict, output_models_dict, statechart=None):
  123. if statechart is not None:
  124. port_sc = statechart[0].addOutputListener(statechart[2])
  125. INPUT("transformation_execute_MT", None, [operation_name, input_models_dict, output_models_dict])
  126. context = OUTPUT()
  127. if statechart is not None:
  128. while 1:
  129. empty = True
  130. # Fetch output from the MV
  131. response = responses.fetch(0)
  132. if response is not None:
  133. print("Got response from MV: " + str(response))
  134. if response.name == "data_output":
  135. # Got output of MV, so forward to SCCD
  136. statechart[0].addInput(Event("input", statechart[1], response.parameters))
  137. elif response.name == "result":
  138. # Finished execution, so continue and return result
  139. statechart[0].addInput(Event("terminate", statechart[1], []))
  140. return response.parameters[1]
  141. empty = False
  142. # Fetch output from the SC
  143. response = port_sc.fetch(0)
  144. if response is not None:
  145. print("Got response from SC: " + str(response))
  146. if response.name == "output":
  147. controller.addInput(Event("data_input", "action_in", [response.parameters, context]))
  148. empty = False
  149. if empty:
  150. time.sleep(0.01)
  151. else:
  152. return OUTPUT()
  153. def transformation_execute_AL(operation_name, input_models_dict, output_models_dict, statechart=None):
  154. if statechart is not None:
  155. port_sc = statechart[0].addOutputListener(statechart[2])
  156. INPUT("transformation_execute_AL", None, [operation_name, input_models_dict, output_models_dict])
  157. context = OUTPUT()
  158. if statechart is not None:
  159. while 1:
  160. empty = True
  161. # Fetch output from the MV
  162. response = responses.fetch(0)
  163. if response is not None:
  164. print("Got response from MV: " + str(response))
  165. if response.name == "data_output":
  166. # Got output of MV, so forward to SCCD
  167. statechart[0].addInput(Event("input", statechart[1], response.parameters))
  168. elif response.name == "result":
  169. # Finished execution, so continue and return result
  170. statechart[0].addInput(Event("terminate", statechart[1], []))
  171. return response.parameters[1]
  172. empty = False
  173. # Fetch output from the SC
  174. response = port_sc.fetch(0)
  175. if response is not None:
  176. print("Got response from SC: " + str(response))
  177. if response.name == "output":
  178. controller.addInput(Event("data_input", "action_in", [response.parameters, context]))
  179. empty = False
  180. if empty:
  181. time.sleep(0.01)
  182. else:
  183. return OUTPUT()
  184. def transformation_execute_MANUAL(operation_name, input_models_dict, output_models_dict, callback=None):
  185. INPUT("transformation_execute_MANUAL", None, [operation_name, input_models_dict, output_models_dict])
  186. context = OUTPUT()
  187. if callback is not None:
  188. callback(context)
  189. INPUT("exit", context, [])
  190. return OUTPUT()
  191. def permission_modify(model_name, permissions):
  192. INPUT("permission_modify", None, [model_name, permissions])
  193. return OUTPUT()
  194. def permission_owner(model_name, permission):
  195. INPUT("permission_owner", None, [model_name, permission])
  196. return OUTPUT()
  197. def permission_group(model_name, group):
  198. INPUT("permission_group", None, [model_name, group])
  199. return OUTPUT()
  200. def group_create(group_name):
  201. INPUT("group_create", None, [group_name])
  202. return OUTPUT()
  203. def group_delete(group_name):
  204. INPUT("group_delete", None, [group_name])
  205. return OUTPUT()
  206. def group_owner_add(group_name, user_name):
  207. INPUT("group_owner_add", None, [group_name, user_name])
  208. return OUTPUT()
  209. def group_owner_delete(group_name, user_name):
  210. INPUT("group_owner_delete", None, [group_name, user_name])
  211. return OUTPUT()
  212. def group_join(group_name, user_name):
  213. INPUT("group_join", None, [group_name, user_name])
  214. return OUTPUT()
  215. def group_kick(group_name, user_name):
  216. INPUT("group_kick", None, [group_name, user_name])
  217. return OUTPUT()
  218. def group_list():
  219. INPUT("group_list", None, [])
  220. return OUTPUT()
  221. def admin_promote(user_name):
  222. INPUT("admin_promote", None, [user_name])
  223. return OUTPUT()
  224. def admin_demote(user_name):
  225. INPUT("admin_demote", None, [user_name])
  226. return OUTPUT()
  227. def conformance_delete(model_name, metamodel_name):
  228. INPUT("conformance_delete", None, [model_name, metamodel_name])
  229. return OUTPUT()
  230. def conformance_add(model_name, metamodel_name):
  231. INPUT("conformance_add", None, [model_name, metamodel_name])
  232. return OUTPUT()
  233. def folder_create(folder_name):
  234. INPUT("folder_create", None, [folder_name])
  235. return OUTPUT()
  236. def model_types(model_name):
  237. INPUT("model_types", None, [model_name])
  238. return OUTPUT()
  239. def alter_context(model_name, metamodel_name):
  240. INPUT("alter_context", None, [model_name, metamodel_name])
  241. return OUTPUT()
  242. def element_list(model_name, context=None):
  243. INPUT("element_list", context, [model_name])
  244. return OUTPUT()
  245. def element_list_nice(model_name, context=None):
  246. INPUT("element_list_nice", context, [model_name])
  247. return OUTPUT()
  248. def types(model_name, context=None):
  249. INPUT("types", context, [model_name])
  250. return OUTPUT()
  251. def types_full(model_name, context=None):
  252. INPUT("types_full", context, [model_name])
  253. return OUTPUT()
  254. def read_info(model_name, ID, context=None):
  255. INPUT("read_info", context, [model_name, ID])
  256. return OUTPUT()
  257. def read_attrs(model_name, ID, context=None):
  258. INPUT("read_attrs", context, [model_name, ID])
  259. return OUTPUT()
  260. def instantiate(model_name, typename, edge=None, ID="", context=None):
  261. INPUT("instantiate", context, [model_name, typename, edge, ID])
  262. return OUTPUT()
  263. def delete_element(model_name, ID, context=None):
  264. INPUT("delete_element", context, [model_name, ID])
  265. return OUTPUT()
  266. def attr_assign(model_name, ID, attr, value, context=None):
  267. INPUT("attr_assign", context, [model_name, ID, attr, value])
  268. return OUTPUT()
  269. def attr_assign_code(model_name, ID, attr, code, context=None):
  270. INPUT("attr_assign_code", context, [model_name, ID, attr, code])
  271. return OUTPUT()
  272. def attr_delete(model_name, ID, attr, context=None):
  273. INPUT("attr_delete", context, [model_name, ID, attr])
  274. return OUTPUT()
  275. def read_outgoing(model_name, ID, typename, context=None):
  276. INPUT("read_outgoing", context, [model_name, ID, typename])
  277. return OUTPUT()
  278. def read_incoming(model_name, ID, typename, context=None):
  279. INPUT("read_incoming", context, [model_name, ID, typename])
  280. return OUTPUT()
  281. def read_association_source(model_name, ID, context=None):
  282. INPUT("read_association_source", context, [model_name, ID])
  283. return OUTPUT()
  284. def read_association_destination(model_name, ID, context=None):
  285. INPUT("read_association_destination", context, [model_name, ID])
  286. return OUTPUT()
  287. def connections_between(model_name, source, target, context=None):
  288. INPUT("connections_between", context, [model_name, source, target])
  289. return OUTPUT()
  290. def define_attribute(model_name, node, attr_name, attr_type, context=None):
  291. INPUT("define_attribute", context, [model_name, node, attr_name, attr_type])
  292. return OUTPUT()
  293. def all_instances(model_name, type_name, context=None):
  294. INPUT("all_instances", context, [model_name, type_name])
  295. return OUTPUT()
  296. def process_execute(process_name, prefix, callbacks=None):
  297. # for all callbacks to SCs, start up the output port already
  298. sc_ports = {}
  299. for k, v in callbacks.items():
  300. if isinstance(v, (tuple, list)):
  301. # Is a statechart, so register already
  302. sc_ports[k] = v[0].addOutputListener(v[2])
  303. INPUT("process_execute", None, [process_name, prefix])
  304. #TODO this is all pseudo-code
  305. while 1:
  306. operation = OUTPUT()
  307. print("Operation: " + str(operation))
  308. if isinstance(operation, (list, tuple)):
  309. t, name, context = operation
  310. print("Executing operation of type %s with name %s in context %s" % (t, name, context))
  311. if t == "OP":
  312. if name in callbacks:
  313. callbacks[name](context)
  314. INPUT("exit", context, [])
  315. elif t == "SC":
  316. if name in callbacks:
  317. statechart = callbacks[name]
  318. while 1:
  319. empty = True
  320. # Fetch output from the MV
  321. response = responses.fetch(0)
  322. if response is not None:
  323. print("Got response from MV: " + str(response))
  324. if response.name == "data_output":
  325. # Got output of MV, so forward to SCCD
  326. statechart[0].addInput(Event("input", statechart[1], response.parameters))
  327. elif response.name == "result":
  328. # Finished execution, so continue and return result
  329. statechart[0].addInput(Event("terminate", statechart[1], []))
  330. return response.parameters[1]
  331. empty = False
  332. # Fetch output from the SC
  333. response = sc_ports[name].fetch(0)
  334. if response is not None:
  335. print("Got response from SC: " + str(response))
  336. if response.name == "output":
  337. controller.addInput(Event("data_input", "action_in", [response.parameters, context]))
  338. empty = False
  339. if empty:
  340. time.sleep(0.01)
  341. else:
  342. if operation == "Finished":
  343. # Finished execution of the process, so exit
  344. return None
  345. # TODO monitor the new function and execute the correct callback
  346. import threading
  347. thrd = threading.Thread(target=run_controller)
  348. thrd.daemon = True
  349. thrd.start()
  350. responses = controller.addOutputListener("action_out")
  351. controller.addOutputListener("ready").fetch(-1)