Update: An Extending Rational Team Concert 3.x landing page has been created on jazz.net for all of your process extension needs! A plugin called Yari is described here that may be useful for determining the APIs you need for your process extension.
While Rational Team Concert comes with many process configuration options out of the box, you may sometimes find it necessary to code your own process extension for a specific behavior you require. While this task may at first sound daunting, the Extensions Workshop on jazz.net will help you easily set up your development environment and test and create your first process extension. I cannot emphasize enough how beneficial it is to run through this workshop prior to creating your extension.
What this post will focus on is not the mechanics of creating your first process extension, but rather what to do when the extension you need to create isn’t for triggering a build on work item state change as we see in the workshop. How do you determine what services and methods you need to achieve the behavior you desire? In a perfect world, we can simply RTFM. Read the “Fine” Manual. Unfortunately, that manual might be incomplete, hard to follow, hard to find, or non-existent. So, we are left needing a different approach to finding the services we require.
Last week I helped somebody code an extension that would create a new stream, seed it with components from an existing stream, and set up the proper flow targets when a work item is saved in a particular state. We started out with the code from the workshop, which gave us a sample of how to verify that the operation is a work item save and that the work item is newly being set to the proper state. Now what? How do we create a stream, seed the components, and set up the flows?
Whenever I code a new extension, I try first to think of a feature in Rational Team Concert that does something similar to what I want to do. In this case, I know that there is a “Duplicate…” action when I right click a stream under Source Control in the Team Artifacts view. This brings up the Stream editor, with the Components and Flow Targets populated to match the stream I am duplicating. Perfect! I see that hitting Save on the editor actually creates my new stream. Now what I need to do is determine what this editor is doing under the covers. In comes one of the handiest tools I have learned about in eclipse in the last several years: Plug-in Spy.
To bring up the Plug-in Spy, I click on the Stream editor to be sure it is active, then type Alt-Shift-F1. I can see that TeamPlacePart2 is the active editor class, so I click on that link in the Plug-in Spy to open the source. Once inside, I know I’m looking for a save method of some sort. I see there is a TeamPlaceSaveable inner class with a doSave method that looks like a likely candidate. This does a save on an instance of TeamPlaceWorkingCopy.
Next, I select the call to save, right-click, and choose Open Declaration to open the save method in TeamPlaceWorkingCopy. In this method, I see that a NewStreamOperation is being created and executed. I do an Open Declaration on NewStreamOperation, where I see the methods for creating the stream, the components, and the flows. It looks like I’ve got a winner. Next, I create a breakpoint on the call to NewStreamOperation.run and launch a debug client, following the directions in the Extensions Workshop.
In the debug client, I duplicate a stream and hit Save. This triggers my breakpoint and brings up the Debug perspective. I am then able to step through the code up until the point that an actual service call is being made. I see that the service I’ll want to use is IScmService, and the methods being called to create the stream and populate the components are createStream and updateComponents2. I can continue stepping through to find the appropriate API for setting the flow as well.
In summary, I can determine the APIs I need for my process extension by finding a similar function in the RTC eclipse client, determining what class provides that function by using the Plug-in Spy, and then launching a debug client to step through the client code until the appropriate server APIs are invoked. One thing to note is that you may find that the service or methods you want to utilize are not publicly documented. If you decide to go ahead and use them, you are running the risk that they may change or go away in a future release. It is a good idea to test and verify your process extensions when moving from one version to the next.