« Back to University of Duisburg-Essen

RE: Defining constraints

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Defining constraints
Answer
1/8/15 9:19 AM
Hello,
I am actually defining constraints regarding the MEMO OrgML and I have some trouble finding a solution for constraints which can not be solved using cardinalities. I have two main issues:

1. Several constraints require a check if certain relations between class A and B exist and based upon that deliver an error message (i.e. no cyclic relations). The easiest way I could think of doing this would be an IF-clause in the class cardinalities but i don' think that is possible. However the solution I am looking for should be like this: Check if relation a->b exists. If "true", do not allow relation b->a, else do allow b->a. How can i perform this, for example with ADO Script?

2. I need to receive the current value of an attribute belonging to a class A and compare it with a value of an attribute of class B. If an A->B relation exists and these values do not match, an error message should be displayed. I found an example of the EventHandler "EditAttrValue", where an attribute is changed based upon the value of an attribute belonging to a different class. Is that EventHandler appropriate for my needs? If so, how could a solution look like?

Best regards,
Jonas Kaiser

RE: Defining constraints
Answer
1/9/15 3:23 PM as a reply to Jonas Kaiser.
Dear Jonas,
To solve your questions you need Event Handlers. Event Handlers are AdoScripts which are executed when certain events occur. They are defined in  the library attribute: 'External coupling' Please find below a proposal on how to solve your questions. And you can also download the library which contains the solution of the proposal. 

1) Here you can use the event "AfterCreateModelingConnector". This event is triggered after a new connector is inserted into a model in the modelling editor. To realize this issue, please have a look on the following AdoScript

 1ON_EVENT "AfterCreateModelingConnector" {
 2#Assign predefined parameters
 3SET id_ModelId: (modelid)
 4SET id_ObjId: (objid)
 5SET id_ClassId: (classid)
 6SET id_FromObjId: (fromobjid)
 7SET id_ToObjId: (toobjid)
 8#Get the target object name of the created connector
 9CC "Core" GET_OBJ_NAME objid: (id_ToObjId)
10SET sToObjName: (objname)
11#Eval a query: 'Get all objects which are outgoing from sToObjName connected with the relation "a2b".'
12CC "AQL" EVAL_AQL_EXPRESSION expr: ("{\"" + sToObjName + "\"} -> \"a2b\"")
13modelid: (id_ModelId)
14SET l_InConList: (objids)
15#check iteratively, if there exists already a relation between the connected objects.
16FOR i in: (l_InConList) {
17IF (id_FromObjId=(VAL i)) {
18CC "AdoScript" ERRORBOX "Not Allowed!"
19CC "Core" DELETE_CONNECTOR modelid: (id_ModelId) objid: (id_ObjId)
20EXIT
21}
22}
23}

2) For this problem you need the event "AfterEditAttributeValue". This event is triggered after an attribute value was edited in a notebook, the tabular view, or a quick-edit field on the drawing area. 

 1ON_EVENT "AfterEditAttributeValue" {
 2SET id_InstId: (instid)
 3SET id_AttrId: (attrid)
 4SET id_ModelId: (modelid)
 5#Get the ID of the attribute which you want to compare.
 6CC "Core" GET_CLASS_ID objid: (id_InstId)
 7SET id_ClassId: (classid)
 8CC "Core" GET_ATTR_ID classid: (id_ClassId) attrname: "Value"
 9SET id_ValAttrId: (attrid)
10#Do something if the the attribute which you want to compare has been changed.
11IF (id_AttrId=id_ValAttrId) {
12#Call the attribute Value
13CC "Core" GET_ATTR_VAL  objid: (id_InstId) attrid: (id_AttrId)
14SET val_AttrVal: (val)
15#Get the name of the object where the attribute has changed
16CC "Core" GET_OBJ_NAME objid: (id_InstId)
17SET sObjName: (objname)
18#Get all target objects which are connected with the relation "a2b"
19CC "AQL" EVAL_AQL_EXPRESSION expr: ("{\"" + sObjName + "\"} -> \"a2b\"") modelid: (id_ModelId)
20SET l_ToObjIds: (objids)
21#Get the attribute Value of the objects from the output list and compare them with the attribute value of the current object.
22FOR i in: (l_ToObjIds) {
23CC "Core" GET_CLASS_ID objid: (VAL i)
24CC "Core" GET_ATTR_ID classid: (classid) attrname: "Value"
25CC "Core" GET_ATTR_VAL  objid: (VAL i) attrid: (attrid)
26SET val_OutAttrVal: (val)
27IF (val_OutAttrVal!=val_AttrVal) {
28CC "AdoScript" ERRORBOX "The Values of the connected objects do not match!"}}
29#Do the same as above for the source objects which are connected with the relation "a2b"
30CC "AQL" EVAL_AQL_EXPRESSION expr: ("{\"" + sObjName + "\"} <- \"a2b\"") modelid: (id_ModelId)
31SET l_FromObjIds: (objids)
32FOR j in: (l_FromObjIds) {
33CC "Core" GET_CLASS_ID objid: (VAL j)
34CC "Core" GET_ATTR_ID classid: (classid) attrname: "Value"
35CC "Core" GET_ATTR_VAL  objid: (VAL j) attrid: (attrid)
36SET val_OutAttrVal: (val)
37IF (val_OutAttrVal!=val_AttrVal) {
38CC "AdoScript" ERRORBOX "The Values of the connected objects do not match!"
39}
40}
41}
42}

Download: 
Constraints on Relations Library.abl

RE: Defining constraints
Answer
1/29/15 5:18 AM as a reply to Mehmet Albayrak.
Thank you very much, that helped us quite a lot.
Nevertheless, we are confronted with another problem, we cannot find a solution for so far. In certain classes, we implemented an attribute called "ShowTextbox". When this attribute is set to "Yes", a textbox is displayed below the concept and represents a few attributes of this concept. We want to implement a MODI, which sets this attribute to "Yes" in any(!) class, which owns this attribute. Does a solution for that purpose exist?

Best regards,
Jonas Kaiser

RE: Defining constraints
Answer
2/9/15 10:10 AM as a reply to Jonas Kaiser.
    Dear Jonas,

    Firstly to mention, there is a platform implementation for functionality related to your question. In the model editor under "Global Change", (menu item "Edit" -> "Global Change") there is an option to change the value of an attribute for all objects of a particular class. One goes to "Global Change" and adds a query to "Get all objects of class..". In the next step one selects the attribute that one wants to change. This change will then effect all objects of that class.

    However, as you noted, you wish to change this attribute for *all* classes which have the attribute "ShowTextbox". In this case, one can write some AdoScript code to do this. The main points of the code are

    1) Use the command "GET_ALL_OBJS" to get the IDs of all objects in the current model.
    2) For each of these objects we make a call to "GET_ATTR_ID".
    3) The trick is to look for what this call returns - if it returns "-1" we know that the object does not have this attribute. This allows us to only try and change the attribute "ShowTextbox" for objects that actually have this attribute.

The code itself is shown below, and is saved in the database under the filename "Change Attribute Value for all Objects Possessing Attribute.asc".
 1SEND "GET_ACTIVE_MODEL" to:"Modeling" answer:modelid
 2SET id_ModelId:(modelid)
 3# First we retrieve all objects in the active model, and put the object ids in a list "l_objIds"
 4CC "Core" GET_ALL_OBJS modelid:(VAL id_ModelId)
 5SET l_objIds:(objids)
 6
 7# In this case, "Yes" is represented by 1, and "No" by 0 - which is equivalent to the box being checked or
 8# unchecked respectively in the notebook
 9SET n_yesVal:1
10SET n_noVal:0
11
12# The attribute name whose value we wish to change is called "ShowTextbox" here. We have three menu options in the model editor,
13# "Yes" which, for all objects having the attribute "ShowTextbox", changes the value to 1 (i.e. "Yes")
14# "No" which, for all objects having the attribute "ShowTextbox", changes the value to 0 (i.e. "No")
15# "Toggle" which, for all objects having the attribute "ShowTextbox", changes it to 0 if it was previously 1, and 1 if it was previously 0
16IF (s_menuOption = "Yes") {
17    # We loop over the objects in our active model. We perform an attempt to get the ID of the attribute "ShowTextbox" for the current object.
18    # If this attribute doesn't exist for the current object we get a value -1 returned. If we don't get -1 the object has the attribute
19    # and we change its value accordingly.
20    FOR s_objId in:(l_objIds) {
21        CC "Core" GET_CLASS_ID objid:(VAL s_objId)
22        SET id_ClassId:(classid)
23        CC "Core" GET_ATTR_ID classid:(id_ClassId) attrname:"ShowTextbox"
24        IF (attrid != -1) {
25            CC "Core" SET_ATTR_VAL objid:(VAL s_objId) attrname:"ShowTextbox" val:(n_yesVal)
26        }
27   
28    }
29   
30}
31
32IF (s_menuOption = "No") {
33   
34    FOR s_objId in:(l_objIds) {
35        CC "Core" GET_CLASS_ID objid:(VAL s_objId)
36        SET id_ClassId:(classid)
37        CC "Core" GET_ATTR_ID classid:(id_ClassId) attrname:"ShowTextbox")
38       
39        IF (attrid != -1) {
40           CC "Core" SET_ATTR_VAL objid:(VAL s_objId) attrname:"ShowTextbox" val:(n_noVal)
41       
42        }
43   
44    }
45   
46}
47
48IF (s_menuOption = "Toggle") {
49   
50    FOR s_objId in:(l_objIds) {
51        CC "Core" GET_CLASS_ID objid:(VAL s_objId)
52        SET id_ClassId:(classid)
53        CC "Core" GET_ATTR_ID classid:(id_ClassId) attrname:"ShowTextbox"
54   
55        IF (attrid != -1) {
56            CC "Core" GET_ATTR_VAL objid:(VAL s_objId) attrname:"ShowTextbox"
57            # The case of "Toggle" is similar to the above, only that we flip the value of the attribute from "Yes" to "No" and vice versa.
58            IF (val = n_yesVal) {
59                CC "Core" SET_ATTR_VAL objid:(VAL s_objId) attrname:"ShowTextbox" val:(n_noVal)
60               
61            }
62            
63            IF (val = n_noVal) {
64                CC "Core" SET_ATTR_VAL objid:(VAL s_objId) attrname:"ShowTextbox" val:(n_yesVal)
65               
66            }
67       
68        }
69   
70    }
71   
72}


The triggering of the script itself, and the definition of some menu items to execute it, are defined in the library attributes under "Add-ons" and then "External coupling".


    There are now three new menu options in the model editor under the "Tools" menu - "Change ShowTextbox to Yes", "Change ShowTextbox to No" and "Toggle ShowTextbox" which execute the AdoScript.

    Please find attached a sample model file (ADL). In this case we have classes A and C, which have the attribute "ShowTextbox", and a class B which does not.
    For clarity, classes A and C will appear as a blue/green circle if it doesn't have its attribute "ShowTextbox" ticked and is shown with a blue/green circle with a cross
    through it if it does have "ShowTextbox" ticked. Class B, which doesn't have the attribute "ShowTextbox", is shown as a red triangle.

    Download:
     Change Attribute Value for all Objects Possessing Attribute.abl   
     Change Attribute Value for all Objects Possessing Attribute.adl