Subclassing the ItemWrapper Class
The ItemWrapper class is the core of the StarTeam Extensions’ workflow logic. There may be situations where the StarTeam Extensions workflow engine cannot support a complex workflow requirement, and in these cases the ItemWrapper can be subclassed and special logic can be implemented by overriding specific class members. The StarTeam Extensions samples include a customization sample that illustrates how to do this. To subclass the ItemWrapper class:
- Create your own class to extend ItemWrapper.
- Override the methods that you need to alter.
- Change the code in the forms that make use of ItemWrapper to create an instance of your class instead of directly creating ItemWrapper instances.
- If you continue using the provided “Launcher” framework, you can simply extend AbstractLauncher or one of its subclasses (like ChangeRequestLauncher), and override the createItemWrapper method. The framework uses this factory method to create ItemWrapper instances, so once you’ve overridden that one method, your subclass will be created wherever an ItemWrapper would have been created.
The methods of ItemWrapper are either public or protected so that they can be overridden. There are just a few methods that you’ll be likely to want to override, however. Following is a brief description of the likely candidate methods to be overridden:
put | This method is used to set the value of any property (except the addition of attachments) of an application Item (ChangeRequest, Requirement, etc.). You should not replace this method unless you have an in-depth understanding of the implications. Rather, this is a good place to put pre- and post-processing logic. If you just want to be notified of a property change, you don’t need to subclass ItemWrapper at all. You can add a PropertyChangeListener to the ItemWrapper instance. If you want to block certain values from being “put”, you will want to override the checkValue method instead. |
checkValue | This method is called within put after checks are made to see that the user is authorized to call put in the first place, that the Item is not read-only, and that the value being put is different than the existing value. Once these conditions are met, checkValue is called with the name of the property and the value that is being set. The default implementation always returns true, but you can override this method to perform any special validation that you want. |
getAllowedValues | This method returns lists of values that are valid “next” values for a particular property. For instance, this method supplies the values for the lists used to select values for Responsibility, LastBuildTested, Priority, Severity, etc. Generally speaking, you will most likely want to simply limit the set of values returned by the default implementation based on your own rules, so it would be best to call the superclass’ method first and then rework that list before returning it. |
isPropertyRequired, isPropertyHidden, isPropertyDisabled | These methods determine whether a particular property requires a non-null value before the Item may be saved, or whether the property’s representation on the form should be hidden or disabled. You might override these if you have special logic that depends on other elements of the Item’s state. |
isAuthorized | This method determines if the user is allowed to edit the Item. You might override these if you have special logic that depends on other elements of the Item’s state. |
update | This method causes the changes to the Item to be saved in the repository. The same warnings apply as with put. Similar to put, if you want to perform some validation before allowing the changes to be saved, you will want to override the validateProperties method instead. |
validateProperties | This method is called within the update call to validate that all requirements are met before the changes are saved. If a requirement is not met, the method throws a RequirementNotFulfilledException. |
dynamicDefaults | This method is called with the name of the property that has just been “put” and then sets the default values of other properties based on the workflow rules. You may override this method if you have special logic that cannot be expressed by the workflow rules. The semantics of dynamic defaults is such that dynamic defaults are only set in response to a user changing a property value directly. Therefore, dynamic defaults should not be triggered by the setting of an ancillary property during dynamic defaults processing. In order to allow you to put a property value without triggering dynamic defaults processing, there is a protected, overloaded put method that takes an additional Boolean parameter indicating whether or not to perform dynamic defaults processing. You should use this overloaded method to put property values if you override dynamicDefaults. |