« Back

Default Model - BeforeCreateModelWindow

Combination View Flat View Tree View
Threads [ Previous | Next ]
toggle
Default Model - BeforeCreateModelWindow
community documentation adoscript trigger
Answer
11/04/14 12:01
I would like to know if it is possible to have a model appear automatically for every newly created project for the same library, if I use the BeforeCreateModelWindow event ? The fact is for the modelling that I want to do, the users will have a fixed model basis, which will never change and which (if possible) should never be deleted.

RE: Default Model - BeforeCreateModelWindow
Answer
11/04/14 12:00 as a reply to Anonymous.
The basic idea would be to add event listeners in the "External coupling" library attribute of the dynamic library. You want to consider the following event and configuration:

CREATE MODEL
- CreateModel: this event is triggered when a new model is created. The parameter "modelid" contains the ID of the created model. An important thing here is to check for the type in order to make sure that for specific types, specific actions are taken. An example for the implementation could look like the following  - to enact it, add the content of the file to the attribute mentioned above.

1ON_EVENT "CreateModel" {
2  # define a global variable to make sure that the script defined in the file can pick up the modelid
3  SETG nCreatedModelID: (modelid)
4  EXECUTE file: ("db:\\createModel.asc")
5}

This event calls an AdoScript on the local file system or within the database (the example above assumes the attached AdoScript "createModel.asc" resides in the file space of the library.

PREVENT DELETION
In order to prevent deletion, we add an attribute called "Erasable" to all classes and relations. The default value should  be set to 1, meaning that when the user creates a new relation or instance, the flag to delete is true. To make sure that objects created with above script are not deleted, we set in the script "createModel.asc" the attribute value explicitly to 0.

PREVENT INSTANCE DELETION

To prevent instance deletion, add the following event listen to External Coupling. The event listener would check the attribute value of "Erasable", If 0, a message would pop up and the deletion is exited with -1, meaning STOP deletion.

 1ON_EVENT "BeforeDeleteInstance" {
 2  EVENT_LOG msgType:"EVENT_LOG" message: ("BeforeDeleteInstance")
 3  CC "Core" GET_CLASS_NAME classid: (classid)
 4  # This is needes since otherwise any delete of a record row = instance is run through here as well
 5  IF (classname <> "Default Relations") {
 6    SETL nDeleteInstanceID: (instid)
 7    # available parameters are instid, classid, modelid
 8    # check if object is erasable
 9    CC "Core" GET_ATTR_VAL objid: (nDeleteInstanceID) attrname: ("Erasable")
10    SETL bErasable: (val)
11    IF (bErasable = 0) {
12      CC "AdoScript" INFOBOX "This object is part of the default model and cannot be deleted."
13      EXIT -1
14    }
15  }
16}

PREVENT CONNECTOR DELETION
Unfortunately, the logic for relation is a bit more complex and we need to use a workaround since there is not event related to the BEFORE case of relation deletion.
For the meantime, the workaround would be to listen to the DeleteRelationInstance in combination with the DiscardRelationInstance event, allow the deletion of the instance and re-create if Erasable is set to 0. The implemenetation builds on the idea to have a container element as modelattribute that transfers the deleted relation instances and re-creates.

 1ON_EVENT "DiscardRelationInstance" {
 2  CC "Modeling" GET_ACT_MODEL
 3  SETL nCreatedModelID: (modelid)
 4  IF (nCreatedModelID != -1) {
 5    EVENT_LOG msgType:"EVENT_LOG" message: ("DiscardRelationInstance")
 6    CC "Core" GET_ATTR_ID classid:bp-model attrname:"Default Relations"
 7    SETL nRecAttrID: (attrid)
 8    CC "Core" GET_ALL_REC_ATTR_ROW_IDS objid: (nCreatedModelID) attrid: (nRecAttrID)
 9    SETL lRowIDs: (rowids)
10    FOR sRowID in: (lRowIDs) {
11      CC "Core" GET_ATTR_VAL objid: (VAL sRowID) attrname: ("StartNode")
12      SETL nFromInstanceID: (VAL val)
13      CC "Core" GET_ATTR_VAL objid: (VAL sRowID) attrname: ("EndNode")
14      SETL nToInstanceID: (VAL val)
15      CC "Core" GET_ATTR_VAL objid: (VAL sRowID) attrname: ("RelationClass")
16      SETL nRelationClassID: (VAL val)
17      CC "Core" GET_ATTR_VAL objid: (VAL sRowID) attrname: ("Positions")
18      SETL sPositions: (val)
19      CC "Core" GET_ATTR_VAL objid: (VAL sRowID) attrname: ("Variants")
20      SETL sVariants: (val)
21      CC "Core" CREATE_CONNECTOR modelid: (nCreatedModelID) fromobjid: (nFromInstanceID) toobjid: (nToInstanceID) classid: (nRelationClassID)
22      SETL nRelationCreated: (objid)
23      CC "Core" SET_ATTR_VAL objid: (nRelationCreated) attrname: ("Positions") val: (sPositions)
24      CC "Core" SET_ATTR_VAL objid: (nRelationCreated) attrname: ("__Variants__") val: (sVariants)
25      CC "Core" SET_ATTR_VAL objid: (nRelationCreated) attrname: ("Erasable") val:0
26      CC "Core" REMOVE_REC_ROW objid: (nCreatedModelID) attrid: (nRecAttrID) rowid: (VAL sRowID)   
27    }
28  }      
29}
30
31ON_EVENT "DeleteRelationInstance" {
32  EVENT_LOG msgType:"EVENT_LOG" message: ("DeleteRelationInstance")
33  # available and relevant parameters are relationinstanceid, relationclassid, frominstanceid, toinstanceid
34  CC "Core" GET_MODEL_ID objid: (relationinstanceid)
35  SETL nCreatedModelID: (modelid)
36  CC "Core" GET_CLASS_NAME classid: (relationclassid)
37  SETL relationClassName: (classname)
38  # this is important, since the implict relation will result in errors and crashes 
39  IF (relationClassName <> "Is inside") {
40    # check if object is erasable
41    CC "Core" GET_ATTR_VAL objid: (relationinstanceid) attrname: ("Erasable")
42    SETL bErasable: (val)
43    IF (bErasable = 0) { 
44      CC "Core" GET_ATTR_VAL objid: (relationinstanceid) attrname:"Positions"
45      SETG sPositionsVal: (val)
46      CC "Core" GET_ATTR_VAL objid: (relationinstanceid) attrname:"__Variants__"
47      SETG sVariantsVal: (val)
48      # TODO only show this warning if an relation by itslef is deleted, not triggered by an instance deletion
49      # new implementation using a model attribute container to prevent issues with update actions
50      CC "Core" GET_ATTR_ID classid:bp-model attrname:"Default Relations"
51      CC "Core" ADD_REC_ROW objid: (nCreatedModelID) attrid: (attrid)
52      SETL nRelationRowID: (rowid)
53      CC "Core" SET_ATTR_VAL objid: (nRelationRowID) attrname: ("StartNode") val: (STR frominstanceid)
54      CC "Core" SET_ATTR_VAL objid: (nRelationRowID) attrname: ("EndNode") val: (STR toinstanceid)
55      CC "Core" SET_ATTR_VAL objid: (nRelationRowID) attrname: ("Positions") val: (sPositionsVal)
56      CC "Core" SET_ATTR_VAL objid: (nRelationRowID) attrname: ("RelationClass") val: (STR relationclassid)
57      CC "Core" SET_ATTR_VAL objid: (nRelationRowID) attrname: ("Variants") val: (sVariantsVal)
58      CC "AdoScript" INFOBOX "This relation is part of the default model and cannot be deleted."
59    }
60  } 
61}
Attachments: AutoModelCreated - Demonstration Library.abl (15.4k), ExternalCoupling.asc (9.1k), createModel.asc (2.2k)