modelverse.py 31 KB

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