Возможности управления данными > Управление изменениями > Администрирование управления изменениями > Администрирование правил связывания изменения > Преобразование гибкой связи изменения > Преобразование пользовательских связей в гибкие связи изменения
  
Преобразование пользовательских связей в гибкие связи изменения
При наличии пользовательских объектов изменения или связей необходимо выполнить дополнительные действия для их преобразования в гибкие объекты изменения.
Обновите связи процесса управления изменениями - требуется только при наличии пользовательских связей изменения, которые включают дополнительные атрибуты.
Создайте делегат преобразователя для каждого типа пользовательской связи.
Создайте файл правил преобразователя для каждого типа пользовательской связи.
Создайте пользовательский делегат готовности - требуется только в том случае, если предоставленные делегаты готовности не соответствуют требованиям.

Обновление связи процесса управления изменениями
Если пользовательская связь имеет дополнительные атрибуты, ее нельзя преобразовать в связь процесса управления изменениями.
Это можно сделать с помощью утилиты AddColumns. Дополнительные сведения см. в разделе Running the AddColumns Tool (Выполнение инструмента AddColumns).
В следующем разделе приведен пример пользовательской связи с дополнительным атрибутом.

Делегат преобразователя для типа пользовательской связи
Этот делегат позволяет обновить связь процесса управления изменениями с использованием любых уникальных значений из пользовательской унаследованной связи. Сведения о том, как зарегистрировать нового делегата, см. в разделе Properties and Property Files (Свойства и файлы свойств).
В Windchill предоставляются следующие варианты регистрации делегата преобразователя связи:
<!-- Delegates for converting legacy change link to flexible links. -->
<Service context="default" name="wt.change2.flexible.FlexibleChangeLinkConverterDelegate">
<Option selector="wt.change2.FormalizedBy" cardinality="singleton"
serviceClass="wt.change2.flexible.DefaultFlexibleChangeLinkConverterDelegate"
requestor="null"/>
<Option selector="wt.change2.AddressedBy2" cardinality="singleton"
serviceClass="wt.change2.flexible.DefaultFlexibleChangeLinkConverterDelegate"
requestor="null"/>
</Service>
В следующем примере пользовательская унаследованная связь обладает дополнительным атрибутом, который необходимо добавить в связь процесса управления изменениями. В данном примере предполагается, что утилита AddColumns уже выполнена.
Делегат извлекает атрибут из пользовательской унаследованной связи и добавляет его в связь процесса управления изменениями:
package com.myCompany;
public class CustomLinkConverterDelegate extends FlexibleChangeLinkConverterDelegate {
@Override
public void postStoreUpdate(WTValuedMap legacyToFlexibleLinkMap) throws WTException {
Locale locale = SessionHelper.getLocale();
//Go through individual legacy links
for(Object obj: legacyToFlexibleLinkMap.entrySet()){
WTValuedEntry entry = (WTValuedEntry) obj;
ObjectReference legacyLinkRef = (ObjectReference) entry.getKey();
ObjectReference changeProcessRef = (ObjectReference) entry.getValue();

//Get value of custom attribute
CustomFormalizedBy formalizedBy = (CustomFormalizedBy) legacyLinkRef.getObject();
String customLinkValue = formalizedBy.getValue().toString();

//Set value of attribute on Change Process Link
ChangeProcessLink changeProcessLink = (ChangeProcessLink) changeProcessRef.getObject();
PersistableAdapter perAdapter = new PersistableAdapter(changeProcessLink,null,locale,new UpdateOperationIdentifier());
perAdapter.load("CustomLinkValue");
perAdapter.set("CustomLinkValue",customLinkValue);
perAdapter.apply();
try {
changeProcessLink.getPersistInfo().setVerified(true);
} catch (WTPropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
PersistenceHelper.manager.modify(changeProcessLink);
}
}
}
Класс CustomLinkConverterDelegate регистрируется следующим образом:
<Service context="default" name="wt.change2.flexible.FlexibleChangeLinkConverterDelegate">
<Option selector="wt.change2.FormalizedBy" cardinality="singleton"
serviceClass="com.myCompany.CustomLinkConverterDelegate"
requestor="null"/>
</Service>

Файлы правил преобразователя типа пользовательской связи
Для каждой пользовательской связи в системе необходимо создать файлы правил преобразователя пользовательской связи.
Например, необходимо найти файл правил преобразователя связи для com.myCompany.CustomFormalizedBy и присвоить ему следующее наименование:
<Windchill>/codebase/wt/change2/flexible/LinkConverterRule.com.myCompany.CustomFormalizedBy.csv
Дополнительные сведения см. в разделе Настройка правил преобразователя связей.

Пользовательский делегат готовности
Делегат готовности на основе требований определяет, готов ли объект изменения к преобразованию.
В Windchill предоставляются следующие делегаты по умолчанию:
WorkflowReadinessDelegate
ResolutionDateReadinessDelegate
TerminalStateReadinessDelegate
AdministrativeLockReadinessDelegate
* 
TerminalStateReadinessDelegate не является зарегистрированной стандартной функцией. Дополнительные сведения см. в разделе Администрирование терминальных состояний для объектов управления изменениями.
Делегаты готовности по умолчанию определяют, готов ли объект изменения к преобразованию. Если объект передает одну оценку, то этот объект считается готовым к преобразованию независимо от наличия ошибок при проверке других делегатов готовности.
Чтобы изменить это поведение для типа объекта изменения, вызовите следующий интерфейс API для объекта ReadinessInfo: setShouldContinueProcessing(). Если установить для этого интерфейса API значение false, утилита будет прекращать проверку других делегатов в том случае, если объект помечен как не готовый для преобразования.
В Windchill предоставляются следующие службы для конфигурирования делегатов готовности:
wt.change2.flexible.FlexibleChangeItemReadinessDelegate.convertLinks
wt.change2.flexible.FlexibleChangeItemReadinessDelegate.convertReplicatedLinks
Каждый делегат должен быть зарегистрирован с уникальным целочисленным значением selector, которое больше нуля. Если зарегистрировано два или более делегатов готовности, они используются в порядке возрастания значения селектора.
Вначале служба wt.change2.flexible.FlexibleChangeItemReadinessDelegate.convertLinks вызывает AdministrativeLockReadinessDelegate, чтобы проверить, не является ли объект изменения административно заблокированным. При обнаружении блокировки делегат возвращает объект ReadinessInfo, содержащий следующие значения:
Для флага isReady устанавливается значение false
Для флага shouldContinueProcessing устанавливается значение false
Обработка текущего административно заблокированного объекта останавливается с прекращением дальнейших проверок готовности.
Если объект не заблокирован, вызывается делегат ResolutionDateReadinessDelegate, чтобы определить готовность объекта изменения для преобразования. Если объект не готов, вызывается делегат WorkflowReadinessDelegate.
Служба wt.change2.flexible.FlexibleChangeItemReadinessDelegate.convertReplicatedLinks не вызывает AdministrativeLockReadinessDelegate.
В следующем примере представлена конфигурация для стандартных делегатов готовности:
<!-- Delegates for computing readiness state for converting legacy change items.
The selector attribute must be unique and must be an integer because the delegates
are called in a particular order which is based on the selector value. -->
<Service context="default" name="wt.change2.flexible.FlexibleChangeItemReadinessDelegate.convertLinks">
<Option serviceClass="wt.change2.flexible.AdministrativeLockReadinessDelegate"
selector="10"
requestor="wt.change2.FlexibleChangeItem"
cardinality="singleton"/>
<Option serviceClass="wt.change2.flexible.ResolutionDateReadinessDelegate"
selector="20"
requestor="wt.change2.FlexibleChangeItem"
cardinality="singleton"/>
<Option serviceClass="wt.change2.flexible.WorkflowReadinessDelegate"
selector="30"
requestor="wt.change2.FlexibleChangeItem"
cardinality="singleton"/>
</Service>
<Service context="default" name="wt.change2.flexible.FlexibleChangeItemReadinessDelegate.convertReplicatedLinks">
<Option serviceClass="wt.change2.flexible.ResolutionDateReadinessDelegate"
selector="10"
requestor="wt.change2.FlexibleChangeItem"
cardinality="singleton"/>
<Option serviceClass="wt.change2.flexible.WorkflowReadinessDelegate"
selector="20"
requestor="wt.change2.FlexibleChangeItem"
cardinality="singleton"/>
</Service>
Сведения о том, как зарегистрировать нового делегата, см. в разделе Properties and Property Files (Свойства и файлы свойств).
Следующий пример делегата демонстрирует два действия:
Проверяет, находится ли объект изменения в состоянии Реализация.
Отменяет все остальные делегаты, если объект находится в неправильном состоянии.
package com.myCompany;
public class CustomReadinessDelegate extends FlexibleChangeItemReadinessDelegate {

protected static final String CUSTOM_RESOURCE = CustomConverterResource.class.getName();
private static final Logger logger = Logger.getLogger(CustomReadinessDelegate.class.getName());
@Override
public WTKeyedMap determineReadiness(WTCollection changeItems) throws WTException {
WTKeyedMap changeItemToReadinessMap = new WTKeyedHashMap();
Map<FlexibleChangeItem, Boolean> shouldContinueMap = new HashMap<FlexibleChangeItem, Boolean>();
for (Object object : changeItems) {
ObjectReference changeItemRef = (ObjectReference) object;
ChangeRequest2Custom changeItem = (ChangeRequest2Custom) changeItemRef.getObject();
ReadinessInfo readinessInfo = null;
WTMessage reasonMsg;
boolean isReady = true;
boolean shouldContinue = true;
if (((VersionableChangeItem) changeItem).getState().getState() != State.toState("IMPLEMENTATION")) {
reasonMsg = new WTMessage(CUSTOM_RESOURCE, CustomConverterResource.INCORRECT_STATE,
new Object[] { FlexibleChangeConverterHelper.getDisplayIdentity(changeItem) });
isReady = false;
shouldContinue = false;
} else {
reasonMsg = new WTMessage(CUSTOM_RESOURCE, CustomConverterResource.CORRECT_STATE,
new Object[] { FlexibleChangeConverterHelper.getDisplayIdentity(changeItem) });
}
readinessInfo = new ReadinessInfo(isReady, changeItemRef, reasonMsg);
readinessInfo.setShouldContinueProcessing(shouldContinue);
changeItemToReadinessMap.put(changeItem, readinessInfo);
}
return changeItemToReadinessMap;
}
}
Чтобы выполнять CustomReadinessDelegate перед стандартными делегатами, зарегистрируйте его с меньшим значением selector:
<Service context="default" name="wt.change2.flexible.FlexibleChangeItemReadinessDelegate">
<Option serviceClass=" com.myCompany.CustomReadinessDelegate"
selector="5"
requestor="wt.change2.FlexibleChangeItem"
cardinality="singleton"/>
</Service>