Developing a Custom Check-in Policy using TFS 11 SDK for Java

Posted by: Subodh Sohoni , on 4/14/2012, in Category Visual Studio, VSTS & TFS
Views: 95859
Abstract: In this article, I will take you through the process of creating and deploying a custom check-in policy using TFS SDK 11 for Java.

In this article, I will take you through the process of creating and deploying a check-in policy using TFS SDK 11 for Java. This SDK is at a Beta phase so some changes by the time of RTM cannot be ruled out. You can download TFS SDK 11 for Java from the same page where Team Explorer Everywhere 11 is available http://www.microsoft.com/download/en/details.aspx?id=28983.

Check-in policy is one of the strong points of TFS source control. It checks for some condition being met at the time of check-in and then based upon the success of that condition check, it either allows or disallows the check-in from going ahead. Microsoft provides some standard check-in policies in the box of TFS but the conditions that an organization may want to check can be totally different. It is possible to create and deploy custom check-in policies using the TFS APIs that are published by Microsoft. In TFS SDK 11 for Java, there are certain classes that we can use to create such check-in policies. I assume that you have downloaded and extracted the TFS SDK 11 for Java from the URL provided earlier in the article.

 

Check-in policy that works with Team Explorer Everywhere 11 is a plug-in into Eclipse. Like any plug-in, a custom check-in policy can be developed using Eclipse for plug-in development (only). We can download such a version of Eclipse, that is called the ‘Eclipse for RCP and RAP Developers’ from the page http://www.eclipse.org/downloads/ . Once downloaded, the package can be extracted at a convenient location. I extracted it at D:\Java so that a folder D:\Java\eclipse-rcp-indigo-SR1-win32-x86_64 was created. We can create and test the plugin using this version of Eclipse. Now on my machine, I have two Eclipse installations. First one is for regular Java applications development and another one for Eclipse Plugin development. I installed Team Explorer Everywhere 11 (Beta) on both the instances of Eclipse.

Let me now show you what is there in TFS SDK 11. It contains folders of Documentation (Javadocs), Redistributable components (a JAR named com.microsoft.tfs.sdk-11.0.0 and some native components) and some sample projects to learn how to code using this SDK. We will use the redistributable component for creating the check-in policy.

For understanding the process of creation and deployment of check-in policy, we will take up a case. The case that I am going to take up is of Code Review. Microsoft has implemented code review workflow as standard workflow in TFS using Code Review Request and Code Review Response work items. Unfortunately, at the least in Beta of the TFS 11, that workflow is not available in Team Explorer Everywhere 11. We will bypass those work items and create another work item of the type Code Review. Whenever a developer completes the creation of modification of some code (s)he will put it in a shelveset and create an instance of code review work item and assign it to a reviewer. The name of the shelveset is part of the code review work item data. Reviewer will do the review and if the code is found to be acceptable, will set the status of the code review work item to ‘Approved’. What the check-in policy will do is to check that every check-in has an associated Code Review work item with the status ‘Approved’. If it is not so, it will not allow the check-in from going through.

Let me now develop such a check-in policy and I will take you through the steps as I perform them on my machine.

I have now opened Eclipse for Plugin Development. While doing so, I created a workspace at “D:\Users\Subodh\Workspace for plugins”.

workspace-launcher

If you are using the latest Eclipse (Indigo), take care that you are also using the JVM version later than 1.6.0_17. Eclipse opens in the perspective of Plugin Development which has a plugins view.

Now I am creating a new project of the type Plugin Project.

plug-in-project

In the New Plugin Project creation wizard, I have provided the name com.ssgs.tfs.policies.codereview.

new-plugin-project

On the next page of the wizard, I removed the checkboxes against the options to create activator and UI Contribution.

On the next page, I clicked Finish button without accepting any template. It created the project and opened the Overview (of various properties of project) page.

project-properties

Now I wanted to add the JAR that is provided as a base by Microsoft in the TFS SDK 11 for Java. I right clicked the project name and selected Build Path – Add External Archives.

add-external-archives

I browsed to the Redist – Lib folder under the TFS SDK 11 folder and added the JAR named com.microsoft.tfs.sdk-11.0.0.jar as a Referenced Library. I also copied ‘native’ folder from redist folder of TFS SDK 11 to the project folder. This folder is required to do debugging of the plugin that we develop.

native-folder

Now I am ready to configure the Plugin so that it has all the necessary dependencies and references setup. I opened the META-INF\MANIFEST.MF

manifest

It has many tabs that we need to configure.

On the Overview tab, I just checked that the Java Runtime Environment is set to my machine’s JRE.

java-runtime-environment

On the dependencies tab I set the required plugins to org.eclipse.core.runtime and com.microsoft.tfs.checkinpolicies. I knew this because I had seen it in the sample of the custom check-in policy that is provided in TFS SDK 11 for Java.

policies-codereview

I also imported the packages org.eclipse.jface.dialogs, org.eclipse.swt and org.eclipse.swt.widgets, again as is done in the sample.

On the Extension tab I selected the Extension Point that is provided by Microsoft, com.microsoft.tfs.checkinpolicies.checkinPolicy.

new-extension

It had identified the typeID and class with some standard names that I changed to com.ssgs.tfs.policies.codereview.CodeReviewCheckinPolicyInstance and com.ssgs.tfs.policies.codereview.CodeReviewCheckinPolicyClass respectively. It immediately also changed the name of the Extension Point in the left hand side list

extension-point

In the plugin.xml, these class and type id are reflected correctly but since this class does not exist presently, it shows a warning with a helper sign to create that class

plugin-xml

New Class wizard started. All the necessary information was filled up so I clicked on Finish button.

new-java-class

It created a new class that implements the PolicyInstance interface and all the method stubs that need to be overridden. The First code change I did was to change that implementation interface so that my class now extended PolicyBase class instead of implementing the PolicyInstance interface. PolicyBase has some additional methods like getPendingChanges that I want to use later on.

checkin-policy-class

I started the coding with creating a local static variable that will provide details of the PolicyType.

private final static PolicyType TYPE = new PolicyType(               
"com.ssgs.tfs.policies.codereview.CodeReviewCheckinPolicyInstance",   
"Code Review Check-in Policy",
"Disallows check-in if Code Review work item with approved state is not associated with the check-in",
"This check-in policy forces developers to get their code reviewed from experts before it can be checked in. " +
"It checks for associated work item of the type Code Review that has state of approved.",
"Download the check-in policy package and install it in your Eclipse");

Then I set getPolicyType method to return this policy type

image

I set the constructor to call the constructor of super class. I also did set the properties of CanEdit and Edit to false and set the displayHelp and activate methods to show the appropriate messages. Now I came to the main method of the class and that is ‘evaluate’ method. In the code of this evaluate method, I checked that the PendingChange has an associated work item of the type ‘Code Review’ and the state of that work item is not ‘Not Approved’. This is the code of that all-important evaluate method:

@Override
public PolicyFailure[] evaluate(PolicyContext context)
       throws PolicyEvaluationCancelledException {
final PendingCheckin pc =  getPendingCheckin();
final List<PolicyFailure> failures = new ArrayList<PolicyFailure>();

final WorkItemCheckinInfo[] AssociatedWorkItems = pc.getWorkItems().getCheckedWorkItems();
WorkItem AssociatedCodeReview = null;
String failureReason = "";
for (int i=0; i<AssociatedWorkItems.length; i++) {
    AssociatedCodeReview = AssociatedWorkItems[i].getWorkItem();
    if (AssociatedCodeReview.getType().getName() == "Code Review")
    { break; }
}
if (AssociatedCodeReview != null) {
    if (AssociatedCodeReview.getFields().getField("System.State").getValue().toString().equals("Not Approved"))
{
failureReason = "Code Review Work Item associated but that is not approved by expert";
         failures.add(new PolicyFailure(failureReason, this));
    }
   }
else {
    failureReason = "Code Review Work Item not associated";
    failures.add(new PolicyFailure(failureReason, this));
   }
                     
return failures.toArray(new PolicyFailure[failures.size()]);                     
}

and that’s it!  

Summary: In this article I have shown you, how to create and code a check-in policy using TFS SDK 11 for Java. In the next article I will carry this forward to run / debug it using Eclipse and then deploy it on the developers machine.

The entire source code of this article can be downloaded over here

 

 

 

 

Give a +1 to this article if you think it was well written. Thanks!
Recommended Articles
Subodh Sohoni, Team System MVP, is an MCTS – Microsoft Team Foundation Server – Configuration and Development and also is a Microsoft Certified Trainer(MCT) since 2004. Subodh has his own company and conducts a lot of corporate trainings. He is an M.Tech. in Aircraft Production from IIT Madras. He has over 20 years of experience working in sectors like Production, Marketing, Software development and now Software Training. Follow him on twitter @subodhsohoni


Page copy protected against web site content infringement by Copyscape


User Feedback
Comment posted by Shaw Terwilliger on Thursday, May 24, 2012 9:37 AM
This is a very nice tutorial!  I do have one suggestion.  Instead of copying the SDK JAR and "native" directory into your plug-in project, you can simply take a plug-in dependency on the com.microsoft.tfs.* plug-ins you need.  These plug-ins will provide all the types you need to implement a policy, and your policy plug-in will be using the actual product plug-ins the user has installed (including bug fixes in updates the user has installed).

The sample policy project included with the SDK (samples/com.microsoft.tfs.sdk.samples.checkinpolicy) has dependencies set up in this way.
Comment posted by Subodh Sohoni on Saturday, May 26, 2012 8:05 AM
Hi Shaw,
That is an excellent suggestion!
Being newby in Java, I did not get that when I wrote the article. I just experimented and put forward whatever that came to my mind and worked.
Thank you!

Post your comment
Name:  
E-mail: (Will not be displayed)
Comment:
Insert Cancel