Этот пример охватывает набор стандартных ситуаций, когда ссылки между программными продуктами проекта и требованиями становятся устаревшими после перемещения или переименования одного или нескольких программных продуктов. Скорее тогда удаляя сломанные ссылки и создавая новые таковые, мы хотим обновить существующие ссылки так, чтобы история создания/изменения и другие свойства (описание, ключевые слова, комментарии,..) были сохранены. Показано использование следующих API:
slreq.find
чтобы завладеть записями и ссылками Simulink Requirements ®
find
для поиска требуемой записи в данном ReqSet
getLinks
запрос всех исходящих ссылок в LinkSet
source
краткая информация об источнике ссылки
destination
краткая информация о адресате по ссылке
slreq.Link
для «as stored» целевой информации, которая отличается от «as resolded» Link.destination()
slreq.LinkSet
для обновления адресатов ссылок при перемещении целевого документа
slreq.ReqSet
для обновления ранее импортированного набора при перемещении исходного документа
updateFromDocument
для обновления ранее импортированных ссылок из обновленного документа
slreq.LinkSet
для преобразования существующих «прямых ссылок» в «ссылочных ссылок»
slreq.show
используется для просмотра исходного или целевого конца заданного slreq.Link
В нескольких местах мы также используем наследие rmi
API, унаследованные от Requirements Management Interface (RMI) продукта SLVnV.
Прежде чем вы начнете, убедитесь в чистом начальном состоянии, запустив slreq.clear
команда. Затем введите slreqCCProjectStart
чтобы открыть пример проекта круиз-контроля. Это разархивирует набор связанных файлов программных продуктов в новую подпапку под вашим MATLAB/Projects
папка.
slreq.clear(); slreqCCProjectStart();
Мы сосредоточимся на небольшой части этого Графика Зависимостей Проекта: откройте crs_plant.slx
Модель, которая имеет несколько ссылок на внешний документ Microsoft ® Word crs_reqs.docx
.
open_system('crs_plant');
Перейдите по одной из ссылок, чтобы открыть связанный документ.
rmi('view', 'crs_plant/status', 1);
Документ Word откроется в соответствующем разделе:
Вот как использовать API командной строки и проверить на наличие ссылок из crs_plant.slx
на crs_reqs.docx
.
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); links = linkSet.getLinks(); disp('Original Links to Word document:');
Original Links to Word document:
for i = 1:numel(links) linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') source = links(i).source; disp([' found link from ' strrep(getfullname([bdroot source.id]),newline,'') ... ' to crs_req.docx']); end end
found link from crs_plant/Vehicle1/vehiclespeed to crs_req.docx found link from crs_plant/throttDrv to crs_req.docx found link from crs_plant/status to crs_req.docx found link from crs_plant/throttleCC to crs_req.docx
Откройте Редактор Simulink Requirements путем ввода slreq.editor
в командной строке MATLAB. Вы увидите два загруженных набора требований: crs_req.slreqx
и crs_req_func_spec.slreqx
. Первый набор требований является коллекцией ссылок, импортированных из crs_req.docx
, а второй был создан вручную в Simulink Requirements Editor. Если теперь закрыть документ Word и перейти по той же ссылке из crs_plant/status
Блок Inport, соответствующая импортированная ссылка подсвечивается в редакторе требований, поскольку действие навигации находит соответствующую привязку в загруженном импортированном наборе требований.
Вы по-прежнему можете использовать кнопку Показать в документе, чтобы увидеть связанное Требование в контексте исходного документа.
slreq.editor(); rmidotnet.MSWord.application('kill'); rmi('view', 'crs_plant/status', 1);
Предположим, что получена обновленная версия документа требований с именем crs_req_v2.docx
. Теперь нам нужны ссылки в crs_plant.slx
для целевого задания соответствующих разделов обновленного документа. Для целей этого примера мы сделаем копию исходного документа в той же папке с измененным именем. Затем используем slreq.LinkSet
API для пакетного обновления всех ссылок в заданном LinkSet
для подключения к более новой копии документа:
copyfile(fullfile(pwd, 'documents/crs_req.docx'), fullfile(pwd, 'documents/crs_req_v2.docx')); linkSet.updateDocUri('crs_req.docx', 'crs_req_v2.docx');
Теперь можно перейти по той же ссылке и подтвердить открытие соответствующей версии внешнего документа. Если мы итерируем все ссылки, как и прежде, это подтверждает, что все 4 ссылки обновляются по назначению:
rmi('view', 'crs_plant/status', 1); % updated document opens links = linkSet.getLinks(); disp('Links to Word document after update:');
Links to Word document after update:
for i = 1:numel(links) source = links(i).source; linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') warning(['link from ' source.id ' still points to crs_req.docx']); % should not happen elseif contains(linkTarget.artifact, 'crs_req_v2.docx') disp([' found link from ' strrep(getfullname([bdroot source.id]),newline,' ')... ' to crs_req_v2.docx']); end end
found link from crs_plant/Vehicle1/vehicle speed to crs_req_v2.docx found link from crs_plant/throttDrv to crs_req_v2.docx found link from crs_plant/status to crs_req_v2.docx found link from crs_plant/throttleCC to crs_req_v2.docx
Как показано выше, когда импортированные ссылки доступны в редакторе требований, навигация по ссылке приведет к выбору соответствующего объекта. Однако мы только что обновили ссылки на новую версию документа crs_req_v2.docx
, и нет импортированных ссылок для этого документа. Навигация из блока Simulink в присутствии редактора требований приводит вас непосредственно к внешнему документу Word.
Чтобы избежать этого несоответствия, необходимо обновить ранее импортированные ссылки для связи с обновленным именем документа. Используем slreq.ReqSet
API для выполнения этой задачи. Кроме того, поскольку в обновленном документе могут быть изменены Требования, мы должны использовать updateFromDocument
API для получения по запросу-в обновлений для ссылочных элементов, хранящихся на стороне Simulink Requirements. После этого навигация из модели Simulink определит местоположение совпадающей импортированной ссылки.
Найдите набор требований с импортированными ссылками. Обновите расположение исходного файла и найдите узел Импорт верхнего уровня.
reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req'); reqSet.updateSrcFileLocation('crs_req.docx', 'crs_req_v2.docx'); importNode = reqSet.find('CustomId', 'crs_req_v2');
Обновите импортированные ссылки из исходного файла. Закройте Microsoft Word. Затем перейдите к обновленной ссылке в редакторе требований.
importNode.updateFromDocument(); rmidotnet.MSWord.application('kill'); rmi('view', 'crs_plant/status', 1);
Отменить изменения данных о ссылках, чтобы избежать запросов на закрытие проекта. Закройте проект (также очищает изменения пути MATLAB). Закройте Microsoft Word.
slreq.clear();
prj = simulinkproject(); prj.close();
rmidotnet.MSWord.application('kill');
Как показано в примере использования 1 выше, необходимы дополнительные усилия для поддержания «прямых ссылок» на внешние документы при перемещении или переименовании документов. Лучшим рабочим процессом является преобразование существующих «прямых ссылок» в «ссылочные ссылки», которые являются ссылками, указывающими на импортированные References
в *
.slreqx
файлы и больше не дублируют информацию о местоположении или имени исходного документа. При использовании этой опции связь с внешним исходным документом сохраняется только в наборе требований, на котором размещены импортированные ссылки.
Чтобы продемонстрировать этот рабочий процесс, перезапустите из той же начальной точки, снова откроя Определение требований для Модели круиз-контроля в новой подпапке. Скопируйте модель Simulink в свою директорию и откройте его.
slreqCCProjectStart(); copyfile(fullfile(pwd, 'documents/crs_req.docx'), fullfile(pwd, 'documents/crs_req_v2.docx')); open_system('crs_plant');
Найдите crs_plant
набор ссылок и crs_req
набор требований с импортированными ссылками.
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req');
Затем используем slreq.LinkSet
API для обновления всех прямых ссылок в crs_plant.slmx
. Затем создайте массив всех ссылок в наборе ссылок.
linkSet.redirectLinksToImportedReqs(reqSet); links = linkSet.getLinks();
После обновления LinkSet
таким образом цикл по всем ссылкам, чтобы подтвердить отсутствие «прямых» ссылок на crs_req.docx
файл.
disp('Check for links to original external document:');
Check for links to original external document:
counter = 0; for i = 1:numel(links) linkTarget = links(i).getReferenceInfo(); if contains(linkTarget.artifact, 'crs_req.docx') source = links(i).source; warning(['link from ' source.id ' still points to crs_req.docx']); counter = counter + 1; end end disp([' Total ' num2str(counter) ' links to external document']);
Total 0 links to external document
Перейдите от модели Simulink к обновленной ссылке.
rmi('view', 'crs_plant/status', 1);
Теперь, когда все ссылки указывают на импортированные ссылки, а не на внешний документ, данную трассируемость остаются непротиворечивыми после переименования документа, пока узел Импорт обновляется для нового внешнего имени документа. Как и в Use Case 1, мы будем делать вид, что есть обновленная версия документа с внешними требованиями, придавая нашему документу Word новое имя. Затем мы выполняем необходимое обновление для узла Import, используя те же API, что и раньше. Теперь, поскольку ссылки полагаются на импортированные ссылки и не хранят информацию об импортированном документе, навигация из модели Simulink приводит нас к обновленной ссылке, так же как после выполнения всех шагов Use Case 1.
Ссылка теперь связана с обновленным внешним документом, кнопка [Показать в документе] открывает обновленный (переименованный) документ, и дальнейшая корректировка на стороне LinkSet не требуется.
Найдите набор требований с импортированными ссылками. Обновите расположение исходного файла и найдите узел Импорт верхнего уровня.
reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req'); reqSet.updateSrcFileLocation('crs_req.docx', 'crs_req_v2.docx'); importNode = reqSet.find('CustomId', 'crs_req_v2');
Обновите импортированные ссылки из исходного файла. Затем перейдите к обновленной ссылке в редакторе требований.
importNode.updateFromDocument();
rmi('view', 'crs_plant/status', 1);
Отменить изменения данных о ссылках, чтобы избежать запросов на закрытие проекта. Закройте проект (также очищает изменения пути MATLAB). Закройте Microsoft Word.
slreq.clear();
prj = simulinkproject(); prj.close();
rmidotnet.MSWord.application('kill');
Теперь предположим, что мы разветвляем существующий проект со связанными программными продуктами, и нам нужно создать новый набор переименованных программных продуктов со всеми ссылками трассируемости, как в исходном проекте. Как и прежде, мы извлекем Проект Круиз-Контроля из Определения Требований для Модели Круиз-Контроля в новую подпапку и преобразуем «прямые ссылки» в «ссылочные ссылки», как мы сделали в Use Case 2 выше. Затем мы идем вперед и создадим «новые версии» связанных программных продуктов, сбросив каждую с _
v2.
имя.
После создания переименованных копий модели Simulink, импортированного внешнего документа и набора требований с импортированными требованиями возникает одна проблема: переименованная модель связана со ссылками в исходном наборе требований, а не в переименованном наборе требований. На панели Сведения (Details) в разделе Ссылки (Links) ссылки отображаются неразрешенными, поскольку исходная модель не загружена.
Откройте Проект Круиз-Контроля и откройте crs_plant
модель. Найдите набор ссылок для crs_plant
и набор требований crs_req
.
slreqCCProjectStart(); open_system('models/crs_plant.slx'); linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant'); reqSet = slreq.find('type', 'ReqSet', 'Name', 'crs_req');
Преобразуйте прямые ссылки в ссылочные ссылки. Создайте переименованные копии файлов и сохраните их.
linkSet.redirectLinksToImportedReqs(reqSet); mkdir(fullfile(pwd, 'copied')); save_system('crs_plant', fullfile(pwd, 'copied/crs_plant_v2.slx')); reqSet.save(fullfile(pwd, 'copied/crs_req_v2.slreqx')); copyfile('documents/crs_req.docx', 'copied/crs_req_v2.docx');
Связать переименованный набор требований с переименованным документом. Найдите узел Импорт верхнего уровня.
reqSet.updateSrcFileLocation('crs_req.docx', fullfile(pwd, 'copied/crs_req_v2.docx')); importNode = reqSet.find('CustomId', 'crs_req_v2');
Убедитесь, что содержимое переименованного набора требований совпадает с содержимым переименованного документа путем обновления импортированных ссылок. Перейдите от переименованной модели Simulink к элементу в переименованном наборе требований. Старый элемент в исходном наборе требований подсвечивается, что неправильно.
importNode.updateFromDocument();
rmi('view', 'crs_plant_v2/status', 1);
Аналогично Use Case 1, мы можем использовать LinkSet.updateDocUri(OLD, NEW)
API для обновления ссылок в crs_plant_v2.slmx
для использования переименованного набора требований crs_req_v2.slreqx
в качестве цели ссылки вместо исходного crs_req.slreqx
. Как только это сделано, перейдите снова из блока в переименованной модели. В переименованном наборе требований выбрано требование и устранены ссылки на панели «Сведения» в разделе «Ссылки» справа внизу.
Найдите набор ссылок для новой копии модели, crs_plant_v2
. Обновите имя набора требований, связанное с новой копией модели. Перейдите от переименованной модели Simulink к элементу в переименованном наборе требований. На этот раз он подсвечивает правильный элемент.
linkSet = slreq.find('type', 'LinkSet', 'Name', 'crs_plant_v2'); linkSet.updateDocUri('crs_req.slreqx', 'crs_req_v2.slreqx');
rmi('view', 'crs_plant_v2/status', 1);
Очистите открытые наборы требований и наборы ссылок и закройте открытые модели и проекты, не сохраняя изменений. Закройте Microsoft Word.
slreq.clear(); bdclose('all'); prj = simulinkproject(); prj.close(); rmidotnet.MSWord.application('kill');