以编程方式获取每个构造型链接对象的最佳方式

Best way to programmatically get linked objects per stereotype

提问人:vascobnunes 提问时间:12/18/2020 最后编辑:vascobnunes 更新时间:12/22/2020 访问量:95

问:

我需要以编程方式(javascript)获取每个构造型给定元素的链接对象,即使它不止一个级别。

因此,例如,在下图中,我希望从 el1 和 el2 获得 Obj1,但从不从 Obj2 获得 Obj2。enter image description here

我已经有了这个解决方案,但似乎不太优雅且耗时:

function count(main_str, sub_str) 
    {
    main_str += '';
    sub_str += '';
    if (sub_str.length <= 0) 
    {
        return main_str.length + 1;
    }
       subStr = sub_str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
       return (main_str.match(new RegExp(subStr, 'gi')) || []).length;
    }

function getLinkedObjects(objectID, connectionType, end_or_start) {
    //This function gets the objects linked to the given objectID. It can be filtered by 'connectionType' and by weather the given object is in start or end position.
    if (connectionType == '' || connectionType == 'any') {
        var connector = ""
    } else {
        var connector = " and Connector_type = '"+connectionType+"'"
        }
    if (end_or_start == 'start') {
        var SQLquery = "select obj.Object_ID, obj.Name from (t_object obj inner join (select * from t_connector where start_object_ID = "+objectID+connector+") q on q.End_object_ID = obj.Object_ID) where obj.Object_ID <> "+objectID+connector
    } else if (end_or_start == 'start') {
        var SQLquery = "select obj.Object_ID, obj.Name from (t_object obj inner join (select * from t_connector where end_object_ID = "+objectID+connector+") q on q.start_object_ID = obj.Object_ID) where obj.Object_ID <> "+objectID+connector
    } else if (end_or_start == '' || end_or_start == 'both') {
        var SQLquery = "select distinct obj.Object_ID, obj.Name from (t_object obj inner join (select * from t_connector where (start_object_ID = "+objectID+connector+" or end_object_ID = "+objectID+connector+")) q on (q.Start_object_ID = obj.Object_ID or q.End_object_ID = obj.Object_ID)) where obj.Object_ID <> "+objectID+connector
    } else {
        var SQLquery = ""
    }
    var conn_elements = Repository.GetElementSet(SQLquery, 2);
    return conn_elements;
    }
    
    
function getObjectStream(elemid, stereotype) {
    //This function gets all the stream of objects and/or blocks linked to the given objectID.
    var i = 0
    var streams = []
    var linked_objs = getLinkedObjects(elemid, "", "both");
    for (var l = 0; l < linked_objs.Count; l++) {
        var level1 = getLinkedObjects(linked_objs.GetAt(l).ElementID, "", "both");
        if (linked_objs.GetAt(l).Stereotype == stereotype) {
            var stream = "l0--  " + linked_objs.GetAt(l).Name
            streams.push(stream)    
            break
        } else {
            for (var l1 = 0; l1 < level1.Count; l1++) {
                var level2 = getLinkedObjects(level1.GetAt(l1).ElementID, "", "both");
                if (level1.GetAt(l1).Stereotype == stereotype) {
                    var stream = "l0--  " + linked_objs.GetAt(l).Name + " l1--  " + level1.GetAt(l1).Name
                    streams.push(stream)
                    break
                } else {
                    for (var l2 = 0; l2 < level2.Count; l2++) {
                        if (level2.GetAt(l2).Stereotype == stereotype) {
                            var stream = "l0--  " + linked_objs.GetAt(l).Name + " l1--  " + level1.GetAt(l1).Name + " l2--  " + level2.GetAt(l2).Name
                            streams.push(stream)
                            break
                        }
                    }
                }
            }
        }
    }
    var w = ''
    var level = 5
    for (var f = 0; f < streams.length; f++) {
        levels = count(streams[f], "--")
        if (levels < level) {
            level = levels - 1
            w = streams[f]
            }   
        }       
        var le = "l"+level+"-- "
        var n = w.search(le) + 5;
        var winner = w.substring(n, w.lenght);
        return winner
    }
    
function main() {
    var linked_per_stereotype = getObjectStream(1234, "A");
    Session.Output(linked_per_stereotype);
}

main();

有什么更好的方法建议吗?

谢谢!

企业架构师

评论

0赞 qwerty_so 12/21/2020
把你尝试过的东西和你卡住的地方放进去。届时可能会重新打开。您不会在此处按要求获得代码。
1赞 qwerty_so 12/21/2020
P.S. 用 Javascript 标记让所有的 JS 孩子都看了它,却不知道你正在使用 EA。
0赞 vascobnunes 12/21/2020
好的,谢谢@qwerty_so
1赞 Geert Bellekens 12/22/2020
您是否需要所有具有某种刻板印象的链接元素,或者只是您遇到的第一个元素?在这种情况下,您需要最接近的链接(首先是广度)还是第一个链接(深度优先)。您需要搜索的级别上限是多少?
1赞 Geert Bellekens 12/22/2020
我现在真的没有时间写答案。您可以编写一个一次返回所有 4 个级别的查询,但由于您只需要关闭一个级别,因此逐级查询可能会更快。确保以递归方式调用操作以进入下一个级别,并确保不要回过头来。

答:

1赞 qwerty_so 12/22/2020 #1

我对JS不是很熟悉,这取决于你的模型。所以只是大声思考:如果所需的构造型数量有限(并且具有像 Python 中这样的语言结构,它可能存在于 JS 中,也可能不存在),我只会查询具有构造型的所有元素及其连接器,并按对象 ID 对结果进行哈希处理。因此,我只需从连接器源/结束 ID 索引哈希即可遍历。我认为刻板印象元素的数量相当少,因此这将是一种方法。JOIN

如果您的模型很大并且有大量这些构造型,那么可能无法绕过单个查询。也许 Geert 可以一口气做到这一点。

评论

0赞 vascobnunes 12/24/2020
我只需要获得具有给定(只有一个)构造型的链接对象。如果它不存在于一个级别中,我需要检查下一个级别,依此类推。我的解决方案(脚本)已经这样做了,但我希望有一种更好、更优雅的方式来做到这一点。