simple_class_diagrams.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. from core.element import Element
  2. from state.base import State, STRING, INTEGER, BOOLEAN, TYPE
  3. from core.context.generic import GenericContext
  4. class SCDContext(GenericContext):
  5. def __init__(self, state: State, model: Element, metamodel: Element):
  6. super().__init__(state, model, metamodel)
  7. def _bootstrap_scd(self) -> Element:
  8. scd = self.state.create_nodevalue("SimpleClassDiagrams")
  9. self.state.create_dict(self.state.read_root(), "SimpleClassDiagrams", scd)
  10. self.state.create_dict(scd, "Model", self.state.create_node())
  11. self.state.create_dict(scd, "Metamodel", scd)
  12. super().__init__(self.state, Element(id=scd), Element(id=scd))
  13. # Classes --> elements that will be typed by Class
  14. self.bottom.add_node(Element(value="Element"))
  15. self.bottom.add_node(Element(value="Class"))
  16. self.bottom.add_value(Element(value="Attribute"), Element(value=TYPE))
  17. # Associations --> elements that will be typed by Association
  18. self.bottom.add_edge(Element(value="Association"), Element(value="Class"), Element(value="Class"))
  19. self.bottom.add_edge(Element(value="Inheritance"), Element(value="Element"), Element(value="Element"))
  20. self.bottom.add_edge(Element(value="AttributeLink"), Element(value="Element"), Element(value="Attribute"))
  21. # Attributes --> elements that will be typed by Attribute
  22. self.bottom.add_value(Element(value="Class_lower_cardinality"), Element(value=INTEGER))
  23. self.bottom.add_value(Element(value="Class_upper_cardinality"), Element(value=INTEGER))
  24. self.bottom.add_value(Element(value="Association_source_lower_cardinality"), Element(value=INTEGER))
  25. self.bottom.add_value(Element(value="Association_source_upper_cardinality"), Element(value=INTEGER))
  26. self.bottom.add_value(Element(value="Association_target_lower_cardinality"), Element(value=INTEGER))
  27. self.bottom.add_value(Element(value="Association_target_upper_cardinality"), Element(value=INTEGER))
  28. self.bottom.add_value(Element(value="Attribute_name"), Element(value=STRING))
  29. self.bottom.add_value(Element(value="Attribute_optional"), Element(value=BOOLEAN))
  30. # Attribute instances --> elements that will be typed by one of the Attributes defined above
  31. self.bottom.add_value(Element(value="Attribute_name.name"), Element(value="name"))
  32. self.bottom.add_value(Element(value="Attribute_name.optional"), Element(value=False))
  33. self.bottom.add_value(Element(value="Attribute_optional.name"), Element(value="optional"))
  34. self.bottom.add_value(Element(value="Attribute_optional.optional"), Element(value=False))
  35. self.bottom.add_value(Element(value="Class_lower_cardinality.name"), Element(value="lower_cardinality"))
  36. self.bottom.add_value(Element(value="Class_lower_cardinality.optional"), Element(value=True))
  37. self.bottom.add_value(Element(value="Class_upper_cardinality.name"), Element(value="upper_cardinality"))
  38. self.bottom.add_value(Element(value="Class_upper_cardinality.optional"), Element(value=True))
  39. self.bottom.add_value(Element(value="Association_source_lower_cardinality.name"), Element(value="source_lower_cardinality"))
  40. self.bottom.add_value(Element(value="Association_source_lower_cardinality.optional"), Element(value=True))
  41. self.bottom.add_value(Element(value="Association_source_upper_cardinality.name"), Element(value="source_upper_cardinality"))
  42. self.bottom.add_value(Element(value="Association_source_upper_cardinality.optional"), Element(value=True))
  43. self.bottom.add_value(Element(value="Association_target_lower_cardinality.name"), Element(value="target_lower_cardinality"))
  44. self.bottom.add_value(Element(value="Association_target_lower_cardinality.optional"), Element(value=True))
  45. self.bottom.add_value(Element(value="Association_target_upper_cardinality.name"), Element(value="target_upper_cardinality"))
  46. self.bottom.add_value(Element(value="Association_target_upper_cardinality.optional"), Element(value=True))
  47. # Inheritance instances --> elements that will be typed by Inheritance
  48. self.bottom.add_edge(Element(value="class_inh_element"), Element(value="Class"), Element(value="Element"))
  49. self.bottom.add_edge(Element(value="attribute_inh_element"), Element(value="Attribute"), Element(value="Element"))
  50. self.bottom.add_edge(Element(value="association_inh_element"), Element(value="Association"), Element(value="Element"))
  51. self.bottom.add_edge(Element(value="attributelink_inh_element"), Element(value="AttributeLink"), Element(value="Element"))
  52. # AttributeLinks --> elements that will be typed by AttributeLink
  53. self.bottom.add_edge(Element(value="Class_attr01"), Element(value="Class"), Element(value="Class_lower_cardinality"))
  54. self.bottom.add_edge(Element(value="Class_attr02"), Element(value="Class"), Element(value="Class_upper_cardinality"))
  55. self.bottom.add_edge(Element(value="Association_attr01"), Element(value="Association"), Element(value="Association_source_lower_cardinality"))
  56. self.bottom.add_edge(Element(value="Association_attr02"), Element(value="Association"), Element(value="Association_source_upper_cardinality"))
  57. self.bottom.add_edge(Element(value="Association_attr03"), Element(value="Association"), Element(value="Association_target_lower_cardinality"))
  58. self.bottom.add_edge(Element(value="Association_attr04"), Element(value="Association"), Element(value="Association_target_upper_cardinality"))
  59. self.bottom.add_edge(Element(value="Attribute_name_link"), Element(value="Attribute"), Element(value="Attribute_name"))
  60. self.bottom.add_edge(Element(value="Attribute_optional_link"), Element(value="Attribute"), Element(value="Attribute_optional"))
  61. # AttributeLink instances --> elements that will be typed by one of the AttributeLink defined above
  62. self.bottom.add_edge(Element(value="Attribute_name_link_01"), Element(value="Attribute_name"), Element(value="Attribute_name.name"))
  63. self.bottom.add_edge(Element(value="Attribute_optional_link_01"), Element(value="Attribute_name"), Element(value="Attribute_name.optional"))
  64. self.bottom.add_edge(Element(value="Attribute_name_link_02"), Element(value="Attribute_optional"), Element(value="Attribute_optional.name"))
  65. self.bottom.add_edge(Element(value="Attribute_optional_link_02"), Element(value="Attribute_optional"), Element(value="Attribute_optional.optional"))
  66. self.bottom.add_edge(Element(value="Attribute_name_link_03"), Element(value="Class_lower_cardinality"), Element(value="Class_lower_cardinality.name"))
  67. self.bottom.add_edge(Element(value="Attribute_optional_link_03"), Element(value="Class_lower_cardinality"), Element(value="Class_lower_cardinality.optional"))
  68. self.bottom.add_edge(Element(value="Attribute_name_link_04"), Element(value="Class_upper_cardinality"), Element(value="Class_upper_cardinality.name"))
  69. self.bottom.add_edge(Element(value="Attribute_optional_link_04"), Element(value="Class_upper_cardinality"), Element(value="Class_upper_cardinality.optional"))
  70. self.bottom.add_edge(Element(value="Attribute_name_link_05"), Element(value="Association_source_lower_cardinality"), Element(value="Association_source_lower_cardinality.name"))
  71. self.bottom.add_edge(Element(value="Attribute_optional_link_05"), Element(value="Association_source_lower_cardinality"), Element(value="Association_source_lower_cardinality.optional"))
  72. self.bottom.add_edge(Element(value="Attribute_name_link_06"), Element(value="Association_source_upper_cardinality"), Element(value="Association_source_upper_cardinality.name"))
  73. self.bottom.add_edge(Element(value="Attribute_optional_link_06"), Element(value="Association_source_upper_cardinality"), Element(value="Association_source_upper_cardinality.optional"))
  74. self.bottom.add_edge(Element(value="Attribute_name_link_07"), Element(value="Association_target_lower_cardinality"), Element(value="Association_target_lower_cardinality.name"))
  75. self.bottom.add_edge(Element(value="Attribute_optional_link_07"), Element(value="Association_target_lower_cardinality"), Element(value="Association_target_lower_cardinality.optional"))
  76. self.bottom.add_edge(Element(value="Attribute_name_link_08"), Element(value="Association_target_upper_cardinality"), Element(value="Association_target_upper_cardinality.name"))
  77. self.bottom.add_edge(Element(value="Attribute_optional_link_08"), Element(value="Association_target_upper_cardinality"), Element(value="Association_target_upper_cardinality.optional"))
  78. """
  79. Retype the elements of the model.
  80. This way we make the model "metacircular".
  81. """
  82. self.retype_element(Element(value="Element"), Element(value="Class"))
  83. self.retype_element(Element(value="Class"), Element(value="Class"))
  84. self.retype_element(Element(value="Attribute"), Element(value="Class"))
  85. self.retype_element(Element(value="Association"), Element(value="Association"))
  86. self.retype_element(Element(value="Inheritance"), Element(value="Association"))
  87. self.retype_element(Element(value="AttributeLink"), Element(value="Association"))
  88. self.retype_element(Element(value="Class_lower_cardinality"), Element(value="Attribute"))
  89. self.retype_element(Element(value="Class_upper_cardinality"), Element(value="Attribute"))
  90. self.retype_element(Element(value="Association_source_lower_cardinality"), Element(value="Attribute"))
  91. self.retype_element(Element(value="Association_source_upper_cardinality"), Element(value="Attribute"))
  92. self.retype_element(Element(value="Association_target_lower_cardinality"), Element(value="Attribute"))
  93. self.retype_element(Element(value="Association_target_upper_cardinality"), Element(value="Attribute"))
  94. self.retype_element(Element(value="Attribute_name"), Element(value="Attribute"))
  95. self.retype_element(Element(value="Attribute_optional"), Element(value="Attribute"))
  96. self.retype_element(Element(value="Class_attr01"), Element(value="AttributeLink"))
  97. self.retype_element(Element(value="Class_attr02"), Element(value="AttributeLink"))
  98. self.retype_element(Element(value="Association_attr01"), Element(value="AttributeLink"))
  99. self.retype_element(Element(value="Association_attr02"), Element(value="AttributeLink"))
  100. self.retype_element(Element(value="Association_attr03"), Element(value="AttributeLink"))
  101. self.retype_element(Element(value="Association_attr04"), Element(value="AttributeLink"))
  102. self.retype_element(Element(value="Attribute_name_link"), Element(value="AttributeLink"))
  103. self.retype_element(Element(value="Attribute_optional_link"), Element(value="AttributeLink"))
  104. self.retype_element(Element(value="class_inh_element"), Element(value="Inheritance"))
  105. self.retype_element(Element(value="attribute_inh_element"), Element(value="Inheritance"))
  106. self.retype_element(Element(value="association_inh_element"), Element(value="Inheritance"))
  107. self.retype_element(Element(value="attributelink_inh_element"), Element(value="Inheritance"))
  108. self.retype_element(Element(value="Attribute_name.name"), Element(value="Attribute_name"))
  109. self.retype_element(Element(value="Attribute_name.optional"),Element(value="Attribute_optional"))
  110. self.retype_element(Element(value="Attribute_optional.name"), Element(value="Attribute_name"))
  111. self.retype_element(Element(value="Attribute_optional.optional"), Element(value="Attribute_optional"))
  112. self.retype_element(Element(value="Class_lower_cardinality.name"), Element(value="Attribute_name"))
  113. self.retype_element(Element(value="Class_lower_cardinality.optional"), Element(value="Attribute_optional"))
  114. self.retype_element(Element(value="Class_upper_cardinality.name"), Element(value="Attribute_name"))
  115. self.retype_element(Element(value="Class_upper_cardinality.optional"), Element(value="Attribute_optional"))
  116. self.retype_element(Element(value="Association_source_lower_cardinality.name"), Element(value="Attribute_name"))
  117. self.retype_element(Element(value="Association_source_lower_cardinality.optional"), Element(value="Attribute_optional"))
  118. self.retype_element(Element(value="Association_source_upper_cardinality.name"), Element(value="Attribute_name"))
  119. self.retype_element(Element(value="Association_source_upper_cardinality.optional"), Element(value="Attribute_optional"))
  120. self.retype_element(Element(value="Association_target_lower_cardinality.name"), Element(value="Attribute_name"))
  121. self.retype_element(Element(value="Association_target_lower_cardinality.optional"), Element(value="Attribute_optional"))
  122. self.retype_element(Element(value="Association_target_upper_cardinality.name"), Element(value="Attribute_name"))
  123. self.retype_element(Element(value="Association_target_upper_cardinality.optional"), Element(value="Attribute_optional"))
  124. self.retype_element(Element(value="Attribute_name_link_01"), Element(value="Attribute_name_link"))
  125. self.retype_element(Element(value="Attribute_optional_link_01"), Element(value="Attribute_optional_link"))
  126. self.retype_element(Element(value="Attribute_name_link_02"), Element(value="Attribute_name_link"))
  127. self.retype_element(Element(value="Attribute_optional_link_02"), Element(value="Attribute_optional_link"))
  128. self.retype_element(Element(value="Attribute_name_link_03"), Element(value="Attribute_name_link"))
  129. self.retype_element(Element(value="Attribute_optional_link_03"), Element(value="Attribute_optional_link"))
  130. self.retype_element(Element(value="Attribute_name_link_04"), Element(value="Attribute_name_link"))
  131. self.retype_element(Element(value="Attribute_optional_link_04"), Element(value="Attribute_optional_link"))
  132. self.retype_element(Element(value="Attribute_name_link_05"), Element(value="Attribute_name_link"))
  133. self.retype_element(Element(value="Attribute_optional_link_05"), Element(value="Attribute_optional_link"))
  134. self.retype_element(Element(value="Attribute_name_link_06"), Element(value="Attribute_name_link"))
  135. self.retype_element(Element(value="Attribute_optional_link_06"), Element(value="Attribute_optional_link"))
  136. self.retype_element(Element(value="Attribute_name_link_07"), Element(value="Attribute_name_link"))
  137. self.retype_element(Element(value="Attribute_optional_link_07"), Element(value="Attribute_optional_link"))
  138. self.retype_element(Element(value="Attribute_name_link_08"), Element(value="Attribute_name_link"))
  139. self.retype_element(Element(value="Attribute_optional_link_08"), Element(value="Attribute_optional_link"))
  140. return Element(id=scd)
  141. def main():
  142. from state.devstate import DevState
  143. s = DevState()
  144. scd = SCDContext(s, Element(), Element())
  145. bootstrap = scd._bootstrap_scd()
  146. model = s.read_dict(bootstrap.id, "Model")
  147. x = []
  148. for e in s.read_outgoing(model):
  149. label_node_edge, = s.read_outgoing(e)
  150. _, label_node = s.read_edge(label_node_edge)
  151. type_node = s.read_dict(label_node, "Type")
  152. x.append(f"{s.read_value(label_node)} : {s.read_value(type_node)}")
  153. for t in sorted(x):
  154. print(t)
  155. # s.dump("out/scd.dot", "out/scd.png")
  156. if __name__ == '__main__':
  157. main()