ARIS Community - We Love BPM

Recursive call to find 'superior' object

mmrenner's picture
by Michael Renner in Reports & Macros posted on 2017-02-13

I have been trying to write a script to find the process-oriented superior of objects.

Initially I thought this would not be very difficult, though I am unable to find a good solution.

I am looping through all Object Occurrences, then I get a connection list for each object:

aCnxDefList = aObjOcc[j].ObjDef().CxnList(); // CxnDef[]

, then I loop through connections comparing names of the known top level superiors with all aCnxDefList[k].SourceObjDef().Name(nLocale). If I don;t get a match, then I call a recursive function:

nCurrentLevel = get_nesting_level(aCnxDefList[k].SourceObjDef(), 0);

I am using a recursive function, but I am unable to walk up to the superior for some reason.I would appreciate any suggestions. Here is the code for the function:

// Takes in Source Object Def
function get_nesting_level(my_ObjDef, myLevelCount) {
    aCxnDef = my_ObjDef.CxnList(Constants.EDGES_IN);
    myLevelCount++; // increment new nesting level
    // cycle through 'Connections IN' to find superior connection match for "CORE", "MANAGEMENT", "ENABLING"
    for (var i=0; i < aCxnDef.length; i++) {
        curSrc_ObjDef = aCxnDef[i].SourceObjDef();
        sObjName = aCxnDef[i].SourceObjDef().Name(nLocale);
            // All objects are children of the following 3 objects
            if((sObjName == 'X') ||
                (sObjName == 'Y') ||
                (sObjName == 'Z'))
                // we found the matching top level!!!
                return (myLevelCount);
                // we did not find the superior yet - recurse another level
                return get_nesting_level(curSrc_ObjDef, myLevelCount);

There are no attachments
Robert Goldenbaum posted on 2017-02-14

Hi Michael,

ahm, this will only give you upper level functions if you really have connections between the functions. Meaning if you have a large VACD with multiple levels of functions, this should work. But if you start it on a function in an EPC, you will never get the upper function, as those two functions are not connected in any way.

BR Robert


Michael Renner posted on 2017-02-14

I am not sure I understand this response Robert.

I am using an EPC model with various objects that have relationships to other objects. If I select a "middle" object in the hierarchy I am thinking it is possible to find the ultimate superior object. Are you saying this is not possible even though ARIS will show relationships?



Robert Goldenbaum posted on 2017-02-15

Hi Michael,

ah well, sure, this is possible !  

But do you want to say that you have an EPC where the start objects have the names you mentioned above ?  Or do you mean you want to go to the superior VACD ?

If you want to get the "start nodes" in an EPC, I would recommend starting from occurrence level, as you never know where the objects are used as well (and then you get a lot of strange things from definition level).

The routine below always gives you the next set of events / functions (and goes over multiple rules if needed). You should definitly add a map to check that you are not going in cycles...


var mObjChecked = new java.util.Hashtable();
mObjChecked.put(oStartObjOcc.ObjDef().GUID() + "_" + oStartObjOcc.X() + "_" + oStartObjOcc.Y(), "");
oObjOccList = GetConnectedStructItems(oStartObjOcc, new Array(), mObjChecked, Constants.EDGES_IN, Constants.OT_FUNC, null);

// ------------------------------------------------------------------------------------------------------------------------
* Recursive function to get all connected structural items in a single direction
// ------------------------------------------------------------------------------------------------------------------------
function GetConnectedStructItems(oCurrentObjOcc, aoReturnOccList, mObjChecked, lDirection, lTypeNum, lSymbolNum){
    var oEdgeList = null;
    var oEdge = null;
    var oOtherObjOcc = null;
    var i = 0; 
    oEdgeList = oCurrentObjOcc.Cxns(lDirection, Constants.EDGES_STRUCTURE);
    for (i = 0 ; i < oEdgeList.length; i++){
        oEdge = oEdgeList[i];
        if (lDirection == Constants.EDGES_OUT){
            oOtherObjOcc = oEdge.TargetObjOcc();
            oOtherObjOcc = oEdge.SourceObjOcc();
        if (!mObjChecked.containsKey(oOtherObjOcc.ObjDef().GUID() + "_" + oOtherObjOcc.X() + "_" + oOtherObjOcc.Y())){
            mObjChecked.put(oOtherObjOcc.ObjDef().GUID() + "_" + oOtherObjOcc.X() + "_" + oOtherObjOcc.Y(), "");
            // check if the item has the correct type
            if (oOtherObjOcc.ObjDef().TypeNum() == lTypeNum){
                // check if the item has the correct symbol
                if (lSymbolNum == null || oOtherObjOcc.SymbolNum() == lSymbolNum){
                if (oOtherObjOcc.ObjDef().TypeNum() == Constants.OT_RULE){
                    GetConnectedStructItems(oOtherObjOcc, aoReturnOccList, mObjChecked, lDirection, lTypeNum, lSymbolNum);
    return aoReturnOccList;

Michael Renner posted on 2017-02-15

"But do you want to say that you have an EPC where the start objects have the names you mentioned above ?  Or do you mean you want to go to the superior VACD ?"

I have my top level objects in a EPC diagram only so your complex approach seems like it should work. I must look further.

Thank you for the kind advice.