Introducing the TFS SDK for Java

June 6, 2011

We recently introduced the TFS SDK for Java, to allow Java developers to target applications to Team Foundation Server. One of the great features of an SDK for Java is that it allows cross-platform access to TFS.

As you might know, I'm the resident Mac guy on the TFS team, so I wanted to whip up a little demo for how you might use this on Mac OS. This little sample shows how to pop up a Growl notification every time a new work item is created that falls within a specific query. Obviously it's fairly simplistic, but hopefully it's a good starting point for thinking about what you might be able to do with the new SDK.

import java.util.HashSet;
import java.util.Set;

import com.microsoft.tfs.core.TFSTeamProjectCollection;
import com.microsoft.tfs.core.clients.workitem.WorkItem;
import com.microsoft.tfs.core.clients.workitem.WorkItemClient;
import com.microsoft.tfs.core.clients.workitem.query.WorkItemCollection;
import com.microsoft.tfs.core.profiles.Profile;
import com.microsoft.tfs.core.profiles.ProfileProperties;

public class WitToast
{
    /*
      * This is a simple WIQL query to execute - work items included
      * in this query will be notified for.
      */
    public static final String WIQL = "select [System.Id], [Microsoft.VSTS.Common.StackRank], [Microsoft.VSTS.Common.Priority], [System.WorkItemType], [System.State], [System.Title] from WorkItems where [System.AssignedTo] = @me and [System.State] <> 'Closed' and [System.WorkItemType] <> 'Shared Steps' order by [Microsoft.VSTS.Common.StackRank], [Microsoft.VSTS.Common.Priority], [System.WorkItemType], [System.Id]";

    public static void main(String[] args) throws Exception {
        Growl growl = new Growl("Team Foundation Server");
        growl.setImageFile("/tmp/tee.icns");

        Set<WorkItem> workItems = new HashSet<WorkItem>();

        /* Build a connection profile */
        Profile profile = new Profile();
        profile.addValue(ProfileProperties.SERVER_URL,
            "http://tfs.contoso.com:8080/tfs/DefaultCollection");
        profile.addValue(ProfileProperties.USER_NAME, "username");
        profile.addValue(ProfileProperties.USER_DOMAIN, "DOMAIN");
        profile.addValue(ProfileProperties.PASSWORD, "Password");

        /* Get the work item SOAP service */
        WorkItemClient wit = new TFSTeamProjectCollection(profile)
            .getWorkItemClient();

        /*
         * Set up the initial set of work items - anything created
         * after this initial query will be notified for.
         */
        WorkItemCollection results = wit.query(WIQL);

        for (int i = 0; i < results.size(); i++) {
            workItems.add(results.getWorkItem(i));
        }

        while (true) {
            results = wit.query(WIQL);

            for (int i = 0; i < results.size(); i++) {
                WorkItem workItem = results.getWorkItem(i);

                /*
                 * This work item hasn't been seen - pop a notification.
                 */
                if (!workItems.contains(workItem)) {
                    growl.notify("The work item " + workItem.getTitle()
                        + " was created.");

                    workItems.add(workItem);
                }
            }

            Thread.sleep(10000);
        }
    }

    private static class Growl
    {
        private final String applicationName;

        public Growl(final String applicationName) {
            this.applicationName = applicationName;
        }

        public void notify(final String message) {
            final String[] growlArguments = new String[5];
            growlArguments[0] = "/usr/local/bin/growlnotify";
            growlArguments[1] = "-n";
            growlArguments[2] = applicationName;
            growlArguments[3] = "-m";
            growlArguments[4] = message;

            try
            {
                Runtime.getRuntime().exec(growlArguments);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    }
}