attribute_ops.py 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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, check_if_last=False):
  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. if check_if_last:
  24. if commons.is_attribute_mandatory(self._node_type, key):
  25. print("Attribute {} for type {} became mandatory, adding it to instance models ...".format(key, self._node_type))
  26. for im in commons.all_instance_models():
  27. nodes = commons.all_nodes_with_type(im, self._node_type)
  28. for nid in nodes:
  29. self.execute(im, nid, key, value, local=True, check_if_last=False)
  30. else:
  31. for m in commons.all_models():
  32. nodes = commons.all_nodes_with_type(m, self._node_type)
  33. for nid in nodes:
  34. self.execute(m, nid, key, value, local=True, check_if_last=False)
  35. def _callback(self, model):
  36. attr_id = mv.instantiate(model, "gm/Attribute")
  37. mv.attr_assign(model, attr_id, "key", self._key)
  38. mv.attr_assign(model, attr_id, "value", self._value)
  39. mv.instantiate(model, "gm/NodeAttribute", ("gm/"+self._node_id, attr_id))
  40. class AttributeDelete(object):
  41. def __init__(self):
  42. self._key = ""
  43. self._node_id = ""
  44. self._node_type = ""
  45. def execute(self, model, node_id, key, local, check_if_last=False):
  46. """
  47. Deletes an attribute identified by its key from node_id in model.
  48. """
  49. self._key = key
  50. self._node_id = node_id
  51. if not self._node_type:
  52. self._node_type = commons.get_node_type(model, node_id)
  53. if local:
  54. mv.transformation_execute_MANUAL("graph_ops/del_attribute", {"gm":model}, {"gm":model},
  55. callback=self._callback)
  56. if check_if_last:
  57. # a local attribute delete can break the conformance for instance models if the attribute was the last in
  58. # all example models -> check and correct this if necessary
  59. for exm in commons.all_example_models():
  60. all_attrs = commons.get_all_attributes_of_type(exm, self._node_type)
  61. for attr in all_attrs:
  62. if attr.key == key:
  63. # wasn't the last, we're done here
  64. return
  65. # it was the last -> delete this attribute in all instance models to maintain conformance
  66. print("Attribute {} was the last, deleting it from all instance models to maintain conformance ...".format(key))
  67. for im in commons.all_instance_models():
  68. nodes = commons.get_nodes_with_attribute(im, key, self._node_type)
  69. for node in nodes:
  70. self.execute(im, node, key, local=True, check_if_last=False)
  71. else:
  72. # delete all attributes with key in all example models
  73. for m in commons.all_models():
  74. nodes = commons.all_nodes_with_type(m, self._node_type)
  75. for nid in nodes:
  76. self.execute(m, nid, key, local=True)
  77. def _callback(self, model):
  78. outgoings = mv.read_outgoing(model, "gm/"+self._node_id, "gm/NodeAttribute")
  79. for edge in outgoings:
  80. attr = mv.read_association_destination(model, edge)[0]
  81. attr_key = mv.read_attrs(model, attr)["key"]
  82. if attr_key == self._key:
  83. mv.delete_element(model, attr)
  84. break
  85. class AttributeChange(object):
  86. """
  87. Remark: This is currently not needed since the UI does not have the functionality to update an attribute
  88. key in-place. Instead, an attribute must be deleted and added with the new key to effectively change the key.
  89. Therefore, this is only here for the sake of completeness.
  90. """
  91. def __init__(self):
  92. self._node_id = ""
  93. self._old_key = ""
  94. self._new_key = ""
  95. self._node_type = ""
  96. def execute(self, model, node_id, old_key, new_key, local):
  97. """
  98. Update the attribute key old_key of node_id in model to new_key.
  99. """
  100. self._node_id = node_id
  101. self._old_key = old_key
  102. self._new_key = new_key
  103. if not self._node_type:
  104. self._node_type = commons.get_node_type(model, node_id)
  105. if local:
  106. mv.transformation_execute_MANUAL("graph_ops/change_attribute", {"gm":model}, {"gm":model},
  107. callback=self._callback)
  108. else:
  109. for m in commons.all_models():
  110. nodes = commons.all_nodes_with_type(m, self._node_type)
  111. for nid in nodes:
  112. self.execute(m, nid, old_key, new_key, local=True)
  113. def _callback(self, model):
  114. outgoings = mv.read_outgoing(model, "gm/"+self._node_id, "gm/NodeAttribute")
  115. for link in outgoings:
  116. attr = mv.read_association_destination(model, link)[0]
  117. attr_key = mv.read_attrs(model, attr)["key"]
  118. if attr_key == self._old_key:
  119. mv.attr_assign(model, attr, "key", self._new_key)
  120. break