|
@@ -11,7 +11,7 @@ class AttributeAdd(object):
|
|
|
self._node_id = ""
|
|
|
self._node_type = ""
|
|
|
|
|
|
- def execute(self, model, node_id, key, value, local, check_if_last=False):
|
|
|
+ def execute(self, model, node_id, key, value, local):
|
|
|
"""
|
|
|
Add a new attribute (key, value) to node with node_id in model.
|
|
|
"""
|
|
@@ -25,18 +25,11 @@ class AttributeAdd(object):
|
|
|
if local:
|
|
|
mv.transformation_execute_MANUAL("graph_ops/add_attribute", {"gm":model}, {"gm":model},
|
|
|
callback=self._callback)
|
|
|
- if check_if_last:
|
|
|
- if commons.is_attribute_mandatory(self._node_type, key):
|
|
|
- print("Attribute {} for type {} became mandatory, adding it to instance models ...".format(key, self._node_type))
|
|
|
- for im in commons.all_instance_models():
|
|
|
- nodes = commons.all_nodes_with_type(im, self._node_type)
|
|
|
- for nid in nodes:
|
|
|
- self.execute(im, nid, key, value, local=True, check_if_last=False)
|
|
|
else:
|
|
|
for m in commons.all_models():
|
|
|
nodes = commons.all_nodes_with_type(m, self._node_type)
|
|
|
for nid in nodes:
|
|
|
- self.execute(m, nid, key, value, local=True, check_if_last=False)
|
|
|
+ self.execute(m, nid, key, value, local=True)
|
|
|
|
|
|
def _callback(self, model):
|
|
|
attr_id = mv.instantiate(model, "gm/Attribute")
|
|
@@ -44,6 +37,21 @@ class AttributeAdd(object):
|
|
|
mv.attr_assign(model, attr_id, "value", self._value)
|
|
|
mv.instantiate(model, "gm/NodeAttribute", ("gm/"+self._node_id, attr_id))
|
|
|
|
|
|
+ def repair(self):
|
|
|
+ """
|
|
|
+ Check if this operation invalidated any instance models by making an attribute mandatory.
|
|
|
+ If yes, every node with the same type must have this attribute, so add it if necessary.
|
|
|
+ """
|
|
|
+ if commons.is_attribute_mandatory(self._node_type, self._key):
|
|
|
+ print("Attribute {} for type {} became mandatory, adding it to instance models ...".format(self._key,
|
|
|
+ self._node_type))
|
|
|
+ for im in commons.all_instance_models():
|
|
|
+ nodes = commons.all_nodes_with_type(im, self._node_type)
|
|
|
+ for node_id in nodes:
|
|
|
+ attrs = commons.get_attributes_of_node(im, node_id)
|
|
|
+ if self._key not in [at.key for at in attrs]:
|
|
|
+ self.execute(im, node_id, self._key, self._value, local=True)
|
|
|
+
|
|
|
|
|
|
class AttributeDelete(object):
|
|
|
def __init__(self):
|
|
@@ -51,7 +59,7 @@ class AttributeDelete(object):
|
|
|
self._node_id = ""
|
|
|
self._node_type = ""
|
|
|
|
|
|
- def execute(self, model, node_id, key, local, check_if_last=False):
|
|
|
+ def execute(self, model, node_id, key, local):
|
|
|
"""
|
|
|
Deletes an attribute identified by its key from node_id in model.
|
|
|
"""
|
|
@@ -64,27 +72,11 @@ class AttributeDelete(object):
|
|
|
if local:
|
|
|
mv.transformation_execute_MANUAL("graph_ops/del_attribute", {"gm":model}, {"gm":model},
|
|
|
callback=self._callback)
|
|
|
- if check_if_last:
|
|
|
- # a local attribute delete can break the conformance for instance models if the attribute was the last in
|
|
|
- # all example models -> check and correct this if necessary
|
|
|
- for exm in commons.all_example_models():
|
|
|
- all_attrs = commons.get_all_attributes_of_type(exm, self._node_type)
|
|
|
- for attr in all_attrs:
|
|
|
- if attr.key == key:
|
|
|
- # wasn't the last, we're done here
|
|
|
- return
|
|
|
- # it was the last -> delete this attribute in all instance models to maintain conformance
|
|
|
- print("Attribute {} was the last, deleting it from all instance models to maintain conformance ...".format(key))
|
|
|
- for im in commons.all_instance_models():
|
|
|
- nodes = commons.get_nodes_with_attribute(im, key, self._node_type)
|
|
|
- for node in nodes:
|
|
|
- self.execute(im, node, key, local=True, check_if_last=False)
|
|
|
else:
|
|
|
- # delete all attributes with key in all example models
|
|
|
- for m in commons.all_models():
|
|
|
- nodes = commons.all_nodes_with_type(m, self._node_type)
|
|
|
+ for exm in commons.all_example_models():
|
|
|
+ nodes = commons.get_nodes_with_attribute(exm, self._key, self._node_type)
|
|
|
for nid in nodes:
|
|
|
- self.execute(m, nid, key, local=True)
|
|
|
+ self.execute(exm, nid, self._key, local=True)
|
|
|
|
|
|
def _callback(self, model):
|
|
|
outgoings = mv.read_outgoing(model, "gm/"+self._node_id, "gm/NodeAttribute")
|
|
@@ -95,6 +87,23 @@ class AttributeDelete(object):
|
|
|
mv.delete_element(model, attr)
|
|
|
break
|
|
|
|
|
|
+ def repair(self):
|
|
|
+ """
|
|
|
+ Check if this operation invalidated any instance models by making an instance model attribute invalid.
|
|
|
+ If yes, delete this attribute from the instance model.
|
|
|
+ """
|
|
|
+ for exm in commons.all_example_models():
|
|
|
+ all_attrs = commons.get_all_attributes_of_type(exm, self._node_type)
|
|
|
+ for attr in all_attrs:
|
|
|
+ if attr.key == self._key:
|
|
|
+ # there still is an attribute with the key, so it is not invalid -> finished
|
|
|
+ return
|
|
|
+ print("Attribute {} was the last, deleting it from all instance models ...".format(self._key))
|
|
|
+ for im in commons.all_instance_models():
|
|
|
+ nodes = commons.get_nodes_with_attribute(im, self._key, self._node_type)
|
|
|
+ for nid in nodes:
|
|
|
+ self.execute(im, nid, self._key, local=True)
|
|
|
+
|
|
|
|
|
|
class AttributeChange(object):
|
|
|
"""
|