attribute_ops.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import sys
  2. sys.path.append("../wrappers")
  3. from wrappers import modelverse as mv
  4. import commons
  5. class AttributeAdd(object):
  6. def __init__(self):
  7. self._key = ""
  8. self._value = ""
  9. self._node_id = ""
  10. self._node_type = ""
  11. def execute(self, model, node_id, key, value, local):
  12. """
  13. Add a new attribute (key, value) to node with node_id in model.
  14. """
  15. self._key = key
  16. self._value = value
  17. self._node_id = node_id
  18. if not self._node_type:
  19. self._node_type = commons.get_node_type(model, node_id)
  20. if local:
  21. mv.transformation_execute_MANUAL("graph_ops/add_attribute", {"gm":model}, {"gm":model},
  22. callback=self._callback)
  23. else:
  24. for m in commons.all_models():
  25. nodes = commons.all_nodes_with_type(m, self._node_type)
  26. for nid in nodes:
  27. self.execute(m, nid, key, value, local=True)
  28. def _callback(self, model):
  29. attr_id = mv.instantiate(model, "gm/Attribute")
  30. mv.attr_assign(model, attr_id, "key", self._key)
  31. mv.attr_assign(model, attr_id, "value", self._value)
  32. mv.instantiate(model, "gm/NodeAttribute", ("gm/"+self._node_id, attr_id))
  33. def repair(self):
  34. """
  35. Check if this operation invalidated any instance models by making an attribute mandatory.
  36. If yes, every node with the same type must have this attribute, so add it if necessary.
  37. """
  38. if commons.is_attribute_mandatory(self._node_type, self._key):
  39. print("Attribute {} for type {} became mandatory, adding it to instance models ...".format(self._key,
  40. self._node_type))
  41. for im in commons.all_instance_models():
  42. nodes = commons.all_nodes_with_type(im, self._node_type)
  43. for node_id in nodes:
  44. attrs = commons.get_attributes_of_node(im, node_id)
  45. if self._key not in [at.key for at in attrs]:
  46. self.execute(im, node_id, self._key, self._value, local=True)
  47. class AttributeDelete(object):
  48. def __init__(self):
  49. self._key = ""
  50. self._node_id = ""
  51. self._node_type = ""
  52. def execute(self, model, node_id, key, local):
  53. """
  54. Deletes an attribute identified by its key from node_id in model.
  55. """
  56. self._key = key
  57. self._node_id = node_id
  58. if not self._node_type:
  59. self._node_type = commons.get_node_type(model, node_id)
  60. if local:
  61. mv.transformation_execute_MANUAL("graph_ops/del_attribute", {"gm":model}, {"gm":model},
  62. callback=self._callback)
  63. else:
  64. for exm in commons.all_example_models():
  65. nodes = commons.get_nodes_with_attribute(exm, self._key, self._node_type)
  66. for nid in nodes:
  67. self.execute(exm, nid, self._key, local=True)
  68. def _callback(self, model):
  69. outgoings = mv.read_outgoing(model, "gm/"+self._node_id, "gm/NodeAttribute")
  70. for edge in outgoings:
  71. attr = mv.read_association_destination(model, edge)[0]
  72. attr_key = mv.read_attrs(model, attr)["key"]
  73. if attr_key == self._key:
  74. mv.delete_element(model, attr)
  75. break
  76. def repair(self):
  77. """
  78. Check if this operation invalidated any instance models by making an instance model attribute invalid.
  79. If yes, delete this attribute from the instance model.
  80. """
  81. for exm in commons.all_example_models():
  82. all_attrs = commons.get_all_attributes_of_type(exm, self._node_type)
  83. for attr in all_attrs:
  84. if attr.key == self._key:
  85. # there still is an attribute with the key, so it is not invalid -> finished
  86. return
  87. print("Attribute {} was the last, deleting it from all instance models ...".format(self._key))
  88. for im in commons.all_instance_models():
  89. nodes = commons.get_nodes_with_attribute(im, self._key, self._node_type)
  90. for nid in nodes:
  91. self.execute(im, nid, self._key, local=True)
  92. class AttributeChange(object):
  93. """
  94. Remark: This is currently not needed since the UI does not have the functionality to update an attribute
  95. key in-place. Instead, an attribute must be deleted and added with the new key to effectively change the key.
  96. Therefore, this is only here for the sake of completeness.
  97. """
  98. def __init__(self):
  99. self._node_id = ""
  100. self._old_key = ""
  101. self._new_key = ""
  102. self._node_type = ""
  103. def execute(self, model, node_id, old_key, new_key, local):
  104. """
  105. Update the attribute key old_key of node_id in model to new_key.
  106. """
  107. self._node_id = node_id
  108. self._old_key = old_key
  109. self._new_key = new_key
  110. if not self._node_type:
  111. self._node_type = commons.get_node_type(model, node_id)
  112. if local:
  113. mv.transformation_execute_MANUAL("graph_ops/change_attribute", {"gm":model}, {"gm":model},
  114. callback=self._callback)
  115. else:
  116. for m in commons.all_models():
  117. nodes = commons.all_nodes_with_type(m, self._node_type)
  118. for nid in nodes:
  119. self.execute(m, nid, old_key, new_key, local=True)
  120. def _callback(self, model):
  121. outgoings = mv.read_outgoing(model, "gm/"+self._node_id, "gm/NodeAttribute")
  122. for link in outgoings:
  123. attr = mv.read_association_destination(model, link)[0]
  124. attr_key = mv.read_attrs(model, attr)["key"]
  125. if attr_key == self._old_key:
  126. mv.attr_assign(model, attr, "key", self._new_key)
  127. break