generic.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. from core.element import Element, String, Boolean
  2. from state.base import State
  3. from core.context.base import Context
  4. from core.context.bottom import BottomContext
  5. class GenericContext(Context):
  6. def __init__(self, state: State, model: Element, metamodel: Element):
  7. super().__init__(state, model, metamodel)
  8. self.bottom = BottomContext(state, model)
  9. def __enter__(self):
  10. pass
  11. def __exit__(self):
  12. pass
  13. def exposed_methods(self):
  14. yield from [
  15. self.instantiate,
  16. self.instantiate_value,
  17. self.instantiate_link,
  18. self.retype_element,
  19. self.delete_element,
  20. self.list_elements,
  21. self.list_types,
  22. self.verify,
  23. ]
  24. def _type_exists(self, type_name: String, instantiate_link: bool) -> bool:
  25. metamodel_root = self.state.read_dict(self.metamodel.id, "Model")
  26. type_element = self.state.read_dict(metamodel_root, type_name.value)
  27. if type_element is None:
  28. return False
  29. else:
  30. element_is_edge = self.state.read_edge(type_element) != (None, None)
  31. return element_is_edge == instantiate_link
  32. def instantiate(self, type_name: String, name: String):
  33. if not self._type_exists(type_name, instantiate_link=False):
  34. print(f"Attempting to instantiate element with invalid type: {type_name.value}")
  35. else:
  36. self.bottom.add_node(name)
  37. self.retype_element(name, type_name)
  38. def instantiate_value(self, type_name: String, name: String, value: Element):
  39. if not self._type_exists(type_name, instantiate_link=False):
  40. print(f"Attempting to instantiate element with invalid type: {type_name.value}")
  41. else:
  42. self.bottom.add_value(name, value)
  43. self.retype_element(name, type_name)
  44. def instantiate_link(self, type_name: String, name: String, source: String, target: String):
  45. if not self._type_exists(type_name, instantiate_link=True):
  46. print(f"Attempting to instantiate link with invalid type: {type_name.value}")
  47. else:
  48. self.bottom.add_edge(name, source, target)
  49. self.retype_element(name, type_name)
  50. def delete_element(self, name: String):
  51. self.bottom.delete_element(name)
  52. def verify(self):
  53. pass # TODO: implement conformance check
  54. def list_elements(self):
  55. model_root = self.state.read_dict(self.model.id, "Model")
  56. unsorted = []
  57. for elem_edge in self.state.read_outgoing(model_root):
  58. # get element name
  59. label_edge, = self.state.read_outgoing(elem_edge)
  60. _, label_node = self.state.read_edge(label_edge)
  61. label = self.state.read_value(label_node)
  62. type_node = self.state.read_dict(label_node, "Type")
  63. type_name = self.state.read_value(type_node)
  64. unsorted.append(f"{label} : {type_name}")
  65. for i in sorted(unsorted):
  66. print(i)
  67. def retype_element(self, name: String, type_name: String):
  68. model_root = self.state.read_dict(self.model.id, "Model")
  69. element_edge = self.state.read_dict_edge(model_root, name.value)
  70. if element_edge is None:
  71. print(f"Error: Element with name {name.value} not found.")
  72. return
  73. label_node_edge, = self.state.read_outgoing(element_edge)
  74. _, label_node = self.state.read_edge(label_node_edge)
  75. # create type name node
  76. type_name_node = self.state.create_nodevalue(type_name.value)
  77. if type_name_node is None:
  78. print("Error: Invalid type name, element not retyped.")
  79. # remove any existing type node
  80. existing = self.state.read_dict(label_node, "Type")
  81. if existing is not None:
  82. self.state.delete_node(existing)
  83. # create new type node
  84. self.state.create_dict(label_node, "Type", type_name_node)