modelverse.py 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. import urllib
  2. import urllib2
  3. import json
  4. import random
  5. from urllib2 import URLError
  6. import sys
  7. # Bind to the compiler (might have to update path manually!)
  8. sys.path.append("../interface/HUTN")
  9. from hutn_compiler.compiler import main as do_compile
  10. # Helper functions and configuration: do not use yourself!
  11. taskname = random.random()
  12. address = None
  13. last_output = None
  14. mode = 0
  15. def _input(value):
  16. # Ugly json encoding of primitives
  17. if isinstance(value, type([])):
  18. value = json.dumps(value)
  19. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "data": value, "taskname": taskname}))).read()
  20. else:
  21. value = json.dumps(value)
  22. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": taskname}))).read()
  23. def _input_raw(value, taskname):
  24. # Ugly json encoding of primitives
  25. urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "set_input", "value": value, "taskname": taskname}))).read()
  26. def _compile_AL(code):
  27. # Compile an action language file and send the compiled code
  28. code_fragments = code.split("\n")
  29. code_fragments = [i for i in code_fragments if i.strip() != ""]
  30. code_fragments = [i.replace(" ", "\t") for i in code_fragments]
  31. initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
  32. code_fragments = [i[initial_tabs:] for i in code_fragments]
  33. code_fragments.append("")
  34. code = "\n".join(code_fragments)
  35. with open("__constraint.alc", "w") as f:
  36. f.write(code)
  37. f.flush()
  38. return do_compile("__constraint.alc", "../interface/HUTN/grammars/actionlanguage.g", "CS")
  39. def _compile_model(code):
  40. # Compile a model and send the compiled graph
  41. # First change multiple spaces to a tab
  42. code_fragments = code.split("\n")
  43. code_fragments = [i for i in code_fragments if i.strip() != ""]
  44. code_fragments = [i.replace(" ", "\t") for i in code_fragments]
  45. initial_tabs = min([len(i) - len(i.lstrip("\t")) for i in code_fragments])
  46. code_fragments = [i[initial_tabs:] for i in code_fragments]
  47. code_fragments.append("")
  48. code = "\n".join(code_fragments)
  49. with open("__model.mvc", "w") as f:
  50. f.write(code)
  51. f.flush()
  52. return do_compile("__model.mvc", "../interface/HUTN/grammars/modelling.g", "M") + ["exit"]
  53. def _output(expected=None):
  54. try:
  55. global last_output
  56. last_output = json.loads(urllib2.urlopen(urllib2.Request(address, urllib.urlencode({"op": "get_output", "taskname": taskname}))).read())
  57. except:
  58. raise UnknownError()
  59. if expected is not None and last_output != expected:
  60. raise InterfaceMismatch(last_output)
  61. return last_output
  62. def _last_output():
  63. return last_output
  64. # Exceptions
  65. class ModelverseException(Exception):
  66. pass
  67. class UnknownException(ModelverseException):
  68. pass
  69. class UnknownIdentifier(ModelverseException):
  70. pass
  71. class UnknownType(ModelverseException):
  72. pass
  73. class NotAnAssociation(ModelverseException):
  74. pass
  75. class UnsupportedValue(ModelverseException):
  76. pass
  77. class CompilationError(ModelverseException):
  78. pass
  79. class NoSuchAttribute(ModelverseException):
  80. pass
  81. class UnknownModel(ModelverseException):
  82. pass
  83. class ConnectionError(ModelverseException):
  84. pass
  85. class ModelExists(ModelverseException):
  86. pass
  87. class PermissionDenied(ModelverseException):
  88. pass
  89. class InvalidMode(ModelverseException):
  90. pass
  91. class InterfaceMismatch(ModelverseException):
  92. pass
  93. # Main MvC operations
  94. def init(address_param="http://localhost:8001"):
  95. """Starts up the connection to the Modelverse."""
  96. # return None
  97. # raises ConnectionError
  98. # raises UnknownError
  99. # raises InvalidMode
  100. global mode
  101. if mode != 0:
  102. raise InvalidMode()
  103. global address
  104. address = address_param
  105. try:
  106. _input_raw('"%s"' % taskname, "task_manager")
  107. mode = 1
  108. except URLError as e:
  109. raise ConnectionError(e.reason)
  110. def login(username, password):
  111. """Log in a user, if user doesn't exist, it is created."""
  112. # return None
  113. # raises UnknownError
  114. # raises PermissionDenied
  115. # raises InterfaceMismatch
  116. global mode
  117. if mode != 1:
  118. raise InvalidMode()
  119. _output("Log on as which user?")
  120. _input(username)
  121. if _output() == "User password?":
  122. _input(password)
  123. if _output() == "Welcome to the Model Management Interface v2.0!":
  124. _output("Use the 'help' command for a list of possible commands")
  125. _output("Ready for command...")
  126. mode = 2
  127. elif _last_output() == "Wrong password!":
  128. raise PermissionDenied()
  129. else:
  130. raise InterfaceMismatch(_last_output())
  131. elif _output() == "This is a new user: please give password!":
  132. _input(password)
  133. _output("Please repeat the password")
  134. _input(password)
  135. if _output() == "Welcome to the Model Management Interface v2.0!":
  136. _output("Use the 'help' command for a list of possible commands")
  137. _output("Ready for command...")
  138. mode = 2
  139. elif _last_output() == "Not the same password!":
  140. # We just sent the same password, so it should be identical, unless the interface changed
  141. raise InterfaceMismatch(_last_output())
  142. else:
  143. raise InterfaceMismatch(_last_output())
  144. else:
  145. raise InterfaceMismatch(_last_output())
  146. def model_add(model_name, metamodel_name, model_code=None):
  147. """Instantiate a new model."""
  148. # return None
  149. # raises UnknownModel
  150. # raises ModelExists
  151. # raises UnknownError
  152. # raises PermissionDenied
  153. # raises CompilationError
  154. if mode != 2:
  155. raise InvalidMode()
  156. # Do this before creating the model, as otherwise compilation errors would make us inconsistent
  157. if model_code is not None:
  158. try:
  159. compiled = _compile_model(model_code)
  160. except:
  161. raise CompilationError()
  162. else:
  163. compiled = ["exit"]
  164. _input("model_add")
  165. _output("Creating new model!")
  166. _output("Model type?")
  167. _input(metamodel_name)
  168. if _output() == "Model name?":
  169. _input(model_name)
  170. if _output() == "Waiting for model constructors...":
  171. _input(compiled)
  172. _output("Model upload success!")
  173. _output("Ready for command...")
  174. elif _last_output() == "Model with that name already exists!":
  175. _output("Ready for command...")
  176. raise ModelExists()
  177. else:
  178. raise InterfaceMismatch(_last_output())
  179. elif _last_output().startswith("Could not find type model"):
  180. _output("Ready for command...")
  181. raise UnknownModel()
  182. elif _last_output() == "Permission denied":
  183. _output("Ready for command...")
  184. raise PermissionDenied()
  185. def model_modify(model_name):
  186. """Modify an existing model."""
  187. # return is_write
  188. # raises UnknownModel
  189. # raises PermissionDenied
  190. # raises UnknownError
  191. global mode
  192. if mode != 2:
  193. raise InvalidMode()
  194. _input("model_modify")
  195. _output("Which model do you want to modify?")
  196. _input(model_name)
  197. if _output() == "Permission denied":
  198. _output("Ready for command...")
  199. raise PermissionDenied()
  200. elif _last_output() == "Could not find model!":
  201. _output("Ready for command...")
  202. raise UnknownModel()
  203. elif _last_output() == "Model loaded, ready for commands!":
  204. mode = 3
  205. if ("r/w" in _output()):
  206. write = True
  207. else:
  208. write = False
  209. _output("Use 'help' command for a list of possible commands")
  210. _output("Please give your command.")
  211. return write
  212. else:
  213. raise InterfaceMismatch()
  214. def model_list():
  215. """List all models."""
  216. # return [(model1, metamodel1), (model2, metamodel2), ...]
  217. # raises UnknownError
  218. if mode != 2:
  219. raise InvalidMode()
  220. _input("model_list")
  221. lst = []
  222. while (_output() != "Ready for command..."):
  223. v = _last_output()
  224. m, mm = v.split(":")
  225. m = m.strip()
  226. mm = mm.strip()
  227. lst.append((m, mm))
  228. return lst
  229. def model_list_full():
  230. """List full information on all models."""
  231. # return [(model1, metamodel1, owner1, group1, permissions1), (model2, metamodel2, owner2, group2, permissions2), ...]
  232. # raises UnknownError
  233. if mode != 2:
  234. raise InvalidMode()
  235. _input("model_list_full")
  236. lst = []
  237. while (_output() != "Ready for command..."):
  238. v = _last_output()
  239. m, mm = v.split(":")
  240. m = m.strip()
  241. mm = mm.strip()
  242. perm, own, grp, m = m.split(" ")
  243. lst.append((m, mm, own, grp, perm))
  244. return lst
  245. def model_overwrite(model_name, new_model=None):
  246. """Upload a new model and overwrite an existing model."""
  247. # return None
  248. # raises UnknownModel
  249. # raises PermissionDenied
  250. # raises CompilationError
  251. # raises UnknownError
  252. if mode != 2:
  253. raise InvalidMode()
  254. if new_model is not None:
  255. try:
  256. compiled = _compile_model(new_model)
  257. except Exception as e:
  258. raise CompilationError(e)
  259. else:
  260. compiled = ["exit"]
  261. _input("model_overwrite")
  262. _output("Which model to overwrite?")
  263. _input(model_name)
  264. if _output() == "Permission denied":
  265. _output("Ready for command...")
  266. raise PermissionDenied()
  267. elif _last_output() == "No such model":
  268. _output("Ready for command...")
  269. raise UnknownModel()
  270. elif _last_output() == "Waiting for model constructors...":
  271. _input(compiled)
  272. _output("Model overwrite success")
  273. _output("Ready for command...")
  274. def user_logout():
  275. """Log out the current user and break the connection."""
  276. # return None
  277. # raises UnknownException
  278. global mode
  279. if mode != 2:
  280. raise InvalidMode()
  281. _input("exit")
  282. mode = 0
  283. def user_delete():
  284. """Removes the current user and break the connection."""
  285. # return None
  286. # raises UnknownException
  287. global mode
  288. if mode != 2:
  289. raise InvalidMode()
  290. _input("self-destruct")
  291. mode = 0
  292. def model_render(model, mapper):
  293. """Fetch a rendered verion of a model."""
  294. # return JSON_representation
  295. # raises UnknownException
  296. # raises UnknownIdentifier
  297. # raises InterfaceMismatch
  298. global mode
  299. if mode != 2:
  300. raise InvalidMode()
  301. _input("model_render")
  302. _output()
  303. _input(model)
  304. _output()
  305. _input(mapper)
  306. rendered = _output()
  307. _output("Ready for command...")
  308. return rendered
  309. def transformation_add_MT_language():
  310. """Create a new Model Transformation language out of a set of metamodels."""
  311. raise NotImplementedError()
  312. def transformation_add_MT():
  313. """Create a new model transformation."""
  314. raise NotImplementedError()
  315. def transformation_add_AL():
  316. """Create a new action language fragment."""
  317. raise NotImplementedError()
  318. def transformation_add_MANUAL():
  319. """Create a new manual model operation."""
  320. raise NotImplementedError()
  321. def transformation_execute():
  322. """Execute an existing model operation."""
  323. raise NotImplementedError()
  324. def transformation_list():
  325. """List existing model operations."""
  326. raise NotImplementedError()
  327. def transformation_list_full():
  328. """List detailed information on model operations."""
  329. raise NotImplementedError()
  330. def transformation_detail():
  331. """List full details of a a model operation."""
  332. raise NotImplementedError()
  333. def transformation_RAMify():
  334. """Ramify an existing metamodel."""
  335. raise NotImplementedError()
  336. def process_execute():
  337. """Execute a process model."""
  338. raise NotImplementedError()
  339. def permission_modify():
  340. """Modify permissions of a model."""
  341. raise NotImplementedError()
  342. def permission_owner():
  343. """Modify the owning user of a model."""
  344. raise NotImplementedError()
  345. def permission_group():
  346. """Modify the owning group of a model."""
  347. raise NotImplementedError()
  348. def group_create():
  349. """Create a new group."""
  350. raise NotImplementedError()
  351. def group_delete():
  352. """Delete a group of which you are an owner."""
  353. raise NotImplementedError()
  354. def group_owner_add():
  355. """Add a new owning user to a group you own."""
  356. raise NotImplementedError()
  357. def group_owner_delete():
  358. """Delete an owning user to a group you own."""
  359. raise NotImplementedError()
  360. def group_join():
  361. """Add a new user to a group you own."""
  362. raise NotImplementedError()
  363. def group_kick():
  364. """Delete a user from a group you own."""
  365. raise NotImplementedError()
  366. def group_list():
  367. """List existing groups."""
  368. raise NotImplementedError()
  369. def admin_promote():
  370. """Promote a user to admin status."""
  371. raise NotImplementedError()
  372. def admin_demote():
  373. """Demote a user from admin status."""
  374. raise NotImplementedError()
  375. # Actual operations on the model
  376. def element_list():
  377. """Return a list of all IDs and the type of the element"""
  378. # return [(name1, type1), (name2, type2), ...]
  379. # raises UnknownError
  380. if mode != 3:
  381. raise InvalidMode()
  382. _input("list")
  383. lst = []
  384. _output("List of all elements:")
  385. while (_output() != "Please give your command."):
  386. v = _last_output()
  387. m, mm = v.split(":")
  388. m = m.strip()
  389. mm = mm.strip()
  390. lst.append((m, mm))
  391. return lst
  392. def types():
  393. """Return a list of all types usable in the model"""
  394. # return [type1, type2, ...]
  395. # raises UnknownError
  396. if mode != 3:
  397. raise InvalidMode()
  398. _input("types")
  399. _output("List of all types:")
  400. lst = []
  401. while (_output() != "Please give your command."):
  402. v = _last_output()
  403. m, mm = v.split(":")
  404. m = m.strip()
  405. lst.append(m)
  406. return lst
  407. def read(ID):
  408. """Return a tuple of information on the element: its type and source/target (None if not an edge)"""
  409. # return (type, (source, target))
  410. # raises UnknownError
  411. # raises UnknownIdentifier
  412. if mode != 3:
  413. raise InvalidMode()
  414. _input("read")
  415. _output("Element to read?")
  416. _input(ID)
  417. _output("ID: " + str(ID))
  418. if _last_output() == "Unknown element; aborting":
  419. _output("Please give your command.")
  420. raise UnknownIdentifier()
  421. else:
  422. t = _output().split(":")[1].strip()
  423. if (not _output().startswith("Source:")):
  424. rval = (t, None)
  425. else:
  426. src = _last_output().split(":")[1].strip()
  427. trg = _output().split(":")[1].strip()
  428. rval = (t, (src, trg))
  429. while (_output() != "Please give your command."):
  430. pass
  431. return rval
  432. def read_attrs(ID):
  433. """Return a dictionary of attribute value pairs"""
  434. # return {attr1: value1, attr2: value2, ...}
  435. # raises UnknownError
  436. # raises UnknownIdentifier
  437. if mode != 3:
  438. raise InvalidMode()
  439. _input("read")
  440. _output("Element to read?")
  441. _input(ID)
  442. _output("ID: " + str(ID))
  443. if _last_output() == "Unknown element; aborting":
  444. _output("Please give your command.")
  445. raise UnknownIdentifier()
  446. else:
  447. rval = {}
  448. # Skip until attributes
  449. while (_output() != "Attributes:"):
  450. pass
  451. while (_output() != "Please give your command."):
  452. r = _last_output()
  453. key, value = r.split(":")
  454. _, value = value.split("=")
  455. key = json.loads(key.strip())
  456. value = value.strip()
  457. value = None if value == "None" else json.loads(value)
  458. rval[key] = value
  459. return rval
  460. def instantiate(typename, edge=None, ID=""):
  461. """Create a new instance of the specified typename, between the selected elements (if not None), and with the provided ID (if any)"""
  462. # return instantiated_ID
  463. # raises UnknownError
  464. # raises UnknownType
  465. # raises UnknownIdentifier
  466. # raises NotAnEdge
  467. if mode != 3:
  468. raise InvalidMode()
  469. _input("instantiate")
  470. if (_output() == "Permission denied"):
  471. _output("Please give your command.")
  472. raise PermissionDenied()
  473. else:
  474. _input(typename)
  475. if (_output() == "Name of new element?"):
  476. _input(ID)
  477. if (_output() == "Element already exists; aborting"):
  478. _output("Please give your command.")
  479. raise ElementExists()
  480. if (edge is not None) and (_last_output() == "Source name?"):
  481. # Is an edge and we have data
  482. _input(edge[0])
  483. if _output() == "Destination name?":
  484. _input(edge[1])
  485. if _output() == "Instantiation successful!":
  486. ID = _output()
  487. _output("Please give your command.")
  488. return ID
  489. elif _last_output() == "Unknown destination; aborting":
  490. _output("Please give your command.")
  491. raise UnknownIdentifier()
  492. else:
  493. raise InterfaceMismatch(_last_output())
  494. elif _last_output() == "Unknown source; aborting":
  495. _output("Please give your command.")
  496. raise UnknownIdentifier()
  497. else:
  498. raise InterfaceMismatch(_last_output())
  499. elif (edge is None) and (_last_output() != "Source name?"):
  500. # Is no edge and we don't have data
  501. ID = _last_output()
  502. _output("Please give your command.")
  503. return ID
  504. elif (edge is not None) and (_last_output() != "Source name?"):
  505. # Is no edge, but we have edge data to input: ERROR
  506. # Delete the element again
  507. ID = _last_output()
  508. _output("Please give your command.")
  509. delete_element(ID)
  510. raise NotAnEdge()
  511. elif (edge is None) and (_last_output() == "Source name?"):
  512. # Is an edge, but we have no edge data to input: ERROR
  513. # Add an empty source, which is guaranteed not to be there
  514. _input("")
  515. _output("Unknown source; aborting")
  516. _output("Please give your command.")
  517. raise NotAnEdge()
  518. elif (_last_output() == "Permission denied"):
  519. _output("Please give your command.")
  520. raise PermissionDenied()
  521. elif (_last_output() == "Unknown type specified; aborting"):
  522. _output("Please give your command.")
  523. raise UnknownType()
  524. else:
  525. raise InterfaceMismatch(_last_output())
  526. def delete_element(ID):
  527. """Delete the element with the given ID"""
  528. # return None
  529. # raises UnknownError
  530. # raises UnknownIdentifier
  531. if mode != 3:
  532. raise InvalidMode()
  533. _input("delete")
  534. if _output() == "What is the name of the element you want to delete?":
  535. _input(ID)
  536. if _output() == "Deleted!":
  537. _output("Please give your command.")
  538. elif _last_output() == "No such element; aborting":
  539. _output("Please give your command.")
  540. raise UnknownIdentifier()
  541. else:
  542. raise InterfaceMismatch(_last_output())
  543. elif _output() == "Permission denied":
  544. _output("Please give your command.")
  545. raise PermissionDenied()
  546. else:
  547. raise InterfaceMismatch(_last_output())
  548. def attr_assign(ID, attr, value):
  549. """Assign a value to an attribute"""
  550. # return None
  551. # raises UnknownError
  552. # raises UnknownIdentifier
  553. # raises NoSuchAttribute
  554. # raises UnsupportedValue
  555. if mode != 3:
  556. raise InvalidMode()
  557. _input("attr_add")
  558. if _output() == "Which element do you want to assign an attribute to?":
  559. _input(ID)
  560. if _output() == "Which attribute do you want to assign?":
  561. _input(attr)
  562. if _output() == "Value of attribute?":
  563. _input(value)
  564. _output("Added attribute!")
  565. _output("Please give your command.")
  566. elif _last_output() == "No such attribute!":
  567. _output("Please give your command.")
  568. raise NoSuchAttribute()
  569. else:
  570. raise InterfaceMismatch(_last_output())
  571. elif _last_output() == "No such element!":
  572. _output("Please give your command.")
  573. raise UnknownIdentifier()
  574. else:
  575. raise InterfaceMismatch(_last_output())
  576. elif _last_output() == "Permission denied":
  577. _output("Please give your command.")
  578. raise PermissionDenied()
  579. else:
  580. raise InterfaceMismatch(_last_output())
  581. def attr_assign_code(ID, attr, code):
  582. """Assign a piece of Action Language code to the attribute"""
  583. # return None
  584. # raises UnknownError
  585. # raises UnknownIdentifier
  586. # raises NoSuchAttribute
  587. # raises UnsupportedValue
  588. if mode != 3:
  589. raise InvalidMode()
  590. try:
  591. compiled = _compile_AL(code)
  592. except Exception as e:
  593. raise CompilationError(e)
  594. _input("attr_add")
  595. if _output() == "Which element do you want to assign an attribute to?":
  596. _input(ID)
  597. if _output() == "Which attribute do you want to assign?":
  598. _input(attr)
  599. if _output() == "Waiting for code constructors...":
  600. _input(compiled)
  601. _output("Added attribute!")
  602. _output("Please give your command.")
  603. elif _last_output() == "No such attribute!":
  604. _output("Please give your command.")
  605. raise NoSuchAttribute()
  606. else:
  607. raise InterfaceMismatch(_last_output())
  608. elif _last_output() == "No such element!":
  609. _output("Please give your command.")
  610. raise UnknownIdentifier()
  611. else:
  612. raise InterfaceMismatch(_last_output())
  613. elif _last_output() == "Permission denied":
  614. _output("Please give your command.")
  615. raise PermissionDenied()
  616. else:
  617. raise InterfaceMismatch(_last_output())
  618. def attr_delete(ID, attr):
  619. """Remove an attribute."""
  620. if mode != 3:
  621. raise InvalidMode()
  622. _input("attr_del")
  623. if _output() == "Which element do you want to remove an attribute of?":
  624. _input(ID)
  625. if _output() == "Which attribute do you want to delete?":
  626. _input(attr)
  627. if _output() == "Attribute deleted!":
  628. _output("Please give your command.")
  629. elif _last_output() == "No such attribute!":
  630. _output("Please give your command.")
  631. raise NoSuchAttribute()
  632. else:
  633. raise InterfaceMismatch(_last_output())
  634. elif _last_output() == "No such element!":
  635. _output("Please give your command.")
  636. raise UnknownIdentifier()
  637. else:
  638. raise InterfaceMismatch(_last_output())
  639. elif _last_output() == "Permission denied":
  640. _output("Please give your command.")
  641. raise PermissionDenied()
  642. else:
  643. raise InterfaceMismatch(_last_output())
  644. def read_outgoing(ID, typename):
  645. """Returns a list of all outgoing associations of a specific type ("" = all)"""
  646. # return [name1, name2, ...]
  647. # raises UnknownError
  648. # raises UnknownIdentifier
  649. if mode != 3:
  650. raise InvalidMode()
  651. _input("read_outgoing")
  652. _output("Element to read from?")
  653. _input(ID)
  654. if _output() == "Type of outgoing edge (empty for all)?":
  655. _input(typename)
  656. lst = []
  657. while (_output() != "Please give your command."):
  658. lst.append(_last_output())
  659. return lst
  660. elif _last_output() == "Unknown element; aborting":
  661. _output("Please give your command.")
  662. raise UnknownIdentifier()
  663. else:
  664. raise InterfaceMismatch()
  665. def read_incoming(ID, typename):
  666. """Returns a list of all incoming associations of a specific type ("" = all)"""
  667. # return [name1, name2, ...]
  668. # raises UnknownError
  669. # raises UnknownIdentifier
  670. # raises UnknownType
  671. if mode != 3:
  672. raise InvalidMode()
  673. _input("read_incoming")
  674. _output("Element to read from?")
  675. _input(ID)
  676. if _output() == "Type of incoming edge (empty for all)?":
  677. _input(typename)
  678. lst = []
  679. while (_output() != "Please give your command."):
  680. lst.append(_last_output())
  681. return lst
  682. elif _last_output() == "Unknown element; aborting":
  683. _output("Please give your command.")
  684. raise UnknownIdentifier()
  685. else:
  686. raise InterfaceMismatch()
  687. def read_association_source(ID):
  688. """Returns the source of an association."""
  689. # returns name
  690. # raises UnknownError
  691. # raises UnknownIdentifier
  692. # raises NotAnAssociation
  693. _input("read_association_source")
  694. _output("Association to read source of?")
  695. _input(ID)
  696. if _output() == "Read source:":
  697. result = _output()
  698. _output("Please give your command.")
  699. return result
  700. elif _last_output() == "Unknown element; aborting":
  701. _output("Please give your command.")
  702. raise UnknownIdentifier()
  703. elif _last_output() == "Not an association; aborting":
  704. _output("Please give your command.")
  705. raise NotAnEdge()
  706. else:
  707. raise InterfaceMismatch(_last_output())
  708. def read_association_destination(ID):
  709. """Returns the destination of an association."""
  710. # returns name
  711. # raises UnknownError
  712. # raises UnknownIdentifier
  713. # raises NotAnAssociation
  714. _input("read_association_destination")
  715. _output("Association to read destination of?")
  716. _input(ID)
  717. if _output() == "Read destination:":
  718. result = _output()
  719. _output("Please give your command.")
  720. return result
  721. elif _last_output() == "Unknown element; aborting":
  722. _output("Please give your command.")
  723. raise UnknownIdentifier()
  724. elif _last_output() == "Not an association; aborting":
  725. _output("Please give your command.")
  726. raise NotAnEdge()
  727. else:
  728. raise InterfaceMismatch(_last_output())
  729. def model_exit():
  730. """Leave model modify mode."""
  731. # return None
  732. # raises UnknownError
  733. global mode
  734. if mode != 3:
  735. raise InvalidMode()
  736. _input("exit")
  737. _output("Ready for command...")
  738. mode = 2