#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. Мне нужно только получить связанные объекты с заданным (только одним) стереотипом. Если он не существует на одном уровне, мне нужно проверить следующий и так далее. Мое решение (сценарий) уже делает это, но я надеялся, что есть лучший и более элегантный способ сделать это.