Лучший способ программного получения связанных объектов для каждого стереотипа

#enterprise-architect

#enterprise-architect

Вопрос:

Мне нужно программно (javascript) получить связанный объект данного элемента для каждого стереотипа, даже если он находится более чем на один уровень выше.

Так, например, на следующем рисунке я ожидаю получить Obj1 как из el1, так и из el2, но никогда Obj2. введите описание изображения здесь

У меня уже есть это решение, но оно кажется не слишком элегантным и требует много времени:

 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, '\$amp;');
       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();
 

Есть предложения по лучшему подходу к этому?

Спасибо!

Комментарии:

1. Добавьте то, что вы пробовали, и где вы застряли. Затем он может быть повторно открыт. Здесь вы не получите код по запросу.

2. P.S. Использование тегов с помощью Javascript заставило всех детей из JS посмотреть на это и не знать, что вы используете EA.

3. хорошо, спасибо @qwerty_so

4. Вам нужны все связанные элементы с определенным стереотипом или только первый, с которым вы сталкиваетесь? В этом случае вам нужен ближайший (сначала в ширину) или первый, если вы перейдете по первой ссылке (сначала в глубину). Есть ли максимальное количество уровней, которые вам нужно искать?

5. Сейчас у меня действительно нет времени писать ответ. Вероятно, вы могли бы написать один запрос, который возвращает все 4 уровня одновременно, но поскольку вам нужен только закрывающий, может быть быстрее запрашивать уровень за уровнем. Убедитесь, что вы вызываете свою операцию рекурсивно, чтобы перейти на следующий уровень, и убедитесь, что вы не возвращаетесь назад.

Ответ №1:

Я не очень хорошо знаком с JS, и это зависит от вашей модели. Итак, просто подумайте вслух: если бы было ограниченное количество желаемых стереотипов (и с языковой конструкцией, подобной Python, которая может присутствовать или отсутствовать в JS), я бы просто запросил все элементы, имеющие стереотип, вместе с их соединителями в a JOIN и сделал хэш результата по идентификатору объекта. Таким образом, я мог бы пройти, просто индексируя хэш из идентификатора источника / конца соединителя. Я бы предположил, что количество стереотипных элементов довольно низкое, так что это был бы подход.

Если ваша модель была огромной и имела тонны этих стереотипов, возможно, не было бы способа обойти отдельные запросы. Возможно, у Гирта есть что-то, что делает это за один раз.

Комментарии:

1. Мне нужно только получить связанные объекты с заданным (только одним) стереотипом. Если он не существует на одном уровне, мне нужно проверить следующий и так далее. Мое решение (сценарий) уже делает это, но я надеялся, что есть лучший и более элегантный способ сделать это.