Advanced Customization > Business Logic Customization > Customizing Change Management > Editing Attributes on the Links of Change Relationship Tables > Customization Procedure > Create a Form Delegate (Step 5)
  
Create a Form Delegate (Step 5)
Most of the change management wizard steps have a 1:1 mapping between the table present on the step and the step themselves. The Change Task wizard is different because it has two tables present.  Each table is processed by its own unique form delegate.  The list of supported form delegates by table is listed below.
Table Name / Step Name
Supporting Classname
Affected Objects (Change Task)
Affected Objects (PR, CR and Var.)
ChangeTaskAffectedItemsFormDelegate
AffectedDataFormDelegate
Affected End-Items
AffectedEndItemsFormDelegate
Resulting Objects
ChangeTaskResultingItemsFormDelegate
Associated Changes
RelatedChangeItemFormDelegate
Affected/Resulting Objects
AffectedAndResultingItemsFormDelegate
It is recommended that you utilize a single form delegate / table. This keeps a clean separation of step vs. table functionality. If you have embedded objects, multiple tables or other scenarios using a step form delegate and delegating this to the table/component sub form delegates is recommended.
Processing Global Attributes of the Link
To process attributes (global attributes or modeled attributes) for a change link table the following is required:
1. Extend the out-of-the-box form delegate.  This provides a lot of APIs and plug-in points for extension as well as handle all of the existing attributes (description, approved quantity, disposition etc.)
2. Override the processLinkAttributes().  This method is called after:
a. The binary links have been created.
b. The type definition reference is set on the link.
c. The link is saved along with the change object.
* 
The purpose of this method is to detect attributes that need to be modified on the links, perform these attribute updates and return a collection of all the links that were modified.  These links are subsequently persisted as a collection.
* 
It is important to only update attributes if they are detected as modified (or cleared)
A new object PersistableAdapter which drastically reduces the amount of code needed to process global attributes. The following code example uses this API.
Several methods on the ChangeLinkAttributeHelper and ChangeManagementClientHelper may prove useful in processing the attributes and extracting FORM data using the changeable reference.
Sample Code
public class DistributingResultingItemsFormDelegate extends
ChangeTaskResultingItemsFormDelegate {

/**
* This method is used to post-process attributes on the change activity
* and change records.
* Note: In the example below we are not checking whether the change
* record is of the type DistributingChangeRecord. This could be done
* by comparing the Type Definition reference of the change record.
* However since this demo is focused on attribute manipulation using the
* new code>LWCNormalzedObject we have left it out for brevity.
*/
@SuppressWarnings("unchecked")
@Override
protected WTCollection processLinkAttributes(ChangeItemIfc item,
WTCollection binaryLinks) throws WTException {
WTCollection modifiedLinks = super.processLinkAttributes(item,
binaryLinks);
if (binaryLinks != null && !binaryLinks.isEmpty() && item instanceof
WTChangeActivity2) {
// The link bean has knowledge of how of link attributes and supports
the JCA interfaces.
ChangeLinkAttributeBean linkBean = ChangeLinkAttributeHelper.
getChangeLinkAttributeBean();
linkBean.setFormData(getObjectBean());
for(Iterator<ChangeRecord2> iter = binaryLinks.persistableIterator(ChangeRecord2.class, true); iter.hasNext(); ) {
ChangeRecord2 record = iter.next();
// The getTableDataValue() will get the attribute from the FORM data
supporting any specific change table handlers
String value = ChangeLinkAttributeHelper.getTableDataValue
(DistributingChangeRecordConstants.DISTRIBUTION_ATTRIBUTE,
ChangeManagementClientHelper.getReference(record.getChangeable2()), linkBean);
// The new LWC API for getting and setting attributes.
PersistableAdapter lwc = new PersistableAdapter(record, null, null, new UpdateOperationIdentifier());
lwc.load(DistributingChangeRecordConstants.DISTRIBUTION_ATTRIBUTE);
Object currentValue = lwc.get(DistributingChangeRecordConstants.
DISTRIBUTION_ATTRIBUTE);
// Only set the attribute if it is different than the current value
if(( value != null && currentValue != null && !value.equals
(currentValue.toString())) || (value == null && currentValue != null) ) {
lwc.set(DistributingChangeRecordConstants.DISTRIBUTION_ATTRIBUTE, value);
lwc.apply();
// calling apply() will require verification, however since this form
delegate is setting the changes we can set it as verified.
try {
record.getPersistInfo().setVerified(true);
} catch (WTPropertyVetoException e) {
e.printStackTrace();
}
modifiedLinks.add(record);
}
}
}
return modifiedLinks;
}
}
Overriding the Step Form Delegate
To override the Affected/Resulting Objects wizard step form delegate:
1. Extend the class AffectedAndResultingItemsFormDelegate
2. Override either the method getAffectedDataFormDelegate() or getResultingDataFormDelegate() and return your custom form delegate for the table.
public class CustomAffectedAndResultingItemsFormDelegate extends
AffectedAndResultingItemsFormDelegate {

@Override
public ObjectFormProcessorDelegate getResultingDataFormDelegate() {
return new DistributingResultingItemsFormDelegate();
}
}