blog community

Welcome to blog community Sign in | Join | Help
in Search

Marcel de Vries, MVP Team System

.NET Technologies, Architecture and Web Development

Code Sample custom policies

using System;

using System.Collections.Generic;

using System.Text;

using Microsoft.TeamFoundation.VersionControl.Client;

using System.Windows.Forms;

using System.Xml;

using System.Collections;

using System.IO;

namespace TeamSystemLabs

{

  public class Strings

  {

    public static string policyType = "XMLDocumentation policy";

    public static string policyDescription = "This policy will check if the developer has XML documentation turned on for a C# project so the build won't fail on missing XML files.";

    public static string policyInstallationInstructions = "To install this policy, download it from the project portal.";

    public static string policyQuestion = "Do you want to turn on the XMLDocumentation policy?";

    public static string policyTypeDescription = "XML Documentation Policy";

    public static string policyDisposedMessage = "Policy Object has been disposed.";

    public static string policyHelp = "Help for policy";

    public static string policyFailureHelpText = "Go to the property page of the c# project and turn on XML Documentation";

    public static string policyViolationMessage = "You must turn on XML documentation in the c# project file {0}.";

    public static string vsDotNetDefaultNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";

    public static string tab = "\t";

  }

 

[Serializable]

public class XmlDocumentationPolicy: IPolicyDefinition, IPolicyEvaluation

{

  #region IPolicyDefinition Members

  // This is the description of a defined policy that is displayed in the UI.

  public string Description

  {

    get { return Strings.policyDescription; }

  }

  public bool CanEdit

  {

    get { return true; }

  }

 

 

// This method is invoked by the policy framework when the user creates a new checkin

// policy or edits an existing checkin policy.  We can use this as an opportunity to

// display UI specific to this policy type allowing the user to change the parameters

// of the policy.

  public bool Edit(IPolicyEditArgs policyEditArgs)

  {

  if (MessageBox.Show(policyEditArgs.Parent, Strings.policyQuestion, "XmlDocument Policy", MessageBoxButtons.YesNo)

                                                                                                      == DialogResult.Yes)

  {

    return true;

  }

  return false;

}

 

// This is a string that is stored with the policy definition on the source

// control server.  If a user does not have our policy plugin installed, this string

// will be displayed.  We can use this as an opportunity to explain to the user

// how they might go about installing our policy plugin.

public string InstallationInstructions

{

  get { return Strings.policyInstallationInstructions; }

}

 

// This string is the type of our policy.  It will be displayed to the user in a list

// of all installed policy types when they are creating a new policy.

public string Type

{

  get { return Strings.policyType; }

}

// This string is a description of the type of our policy.  It will be displayed to the

// user when they select our policy type in the list of policies installed on the system

// as mentioned above.

public string TypeDescription

{

  get { return Strings.policyTypeDescription; }

}

 

#endregion

 

#region IPolicyEvaluation Members

 

// This method performs the actual evaluation.  It is called by the policy framework at various points in time

// when policy should be evaluated.  In this example, we invoke this method ourselves when various asyc

// events occur that may have invalidated the current list of failures.

public PolicyFailure[] Evaluate()

{

  // check the csproj file if xml documentation is turned on.

  ArrayList failures = IsXMLDocumentationTurnedOn();

  if (failures.Count == 0)

      return m_noFailures;

  else

  {

    PolicyFailure[] toReturn = new PolicyFailure[failures.Count];

    failures.CopyTo(toReturn);

    return toReturn;

  }

}

 

private ArrayList IsXMLDocumentationTurnedOn()

{

  // find if there is a csproj file involved

  ArrayList csprojFiles = new ArrayList();

  ArrayList failures = new ArrayList();

           

  foreach(PendingChange change in

                         m_pendingCheckin.PendingChanges.AllPendingChanges)

  {

    if (change.FileName.EndsWith("csproj"))

    {

     // now get the file name including its path

     csprojFiles.Add(change.LocalItem);

    }

  }

 

 if (csprojFiles.Count >0)

 {

  // load the file into the XML document and search for the documentation property

  // the tag looks like this : <DocumentationFile>bin\Debug\XMLDocumentationPolicy.XML</DocumentationFile>

   foreach (string csprojFile in csprojFiles)

   {

     XmlDocument csprojXml = new XmlDocument();

     csprojXml.Load(csprojFile);

     // if the node is there we know the documentation is enabled

     XmlNamespaceManager xmlNS = new XmlNamespaceManager(csprojXml.NameTable);

     xmlNS.AddNamespace("a",Strings.vsDotNetDefaultNamespace);

     XmlNode n = csprojXml.SelectSingleNode("//a:DocumentationFile", xmlNS);

     if ((n == null) || (n.InnerText.Length== 0))

     {

       failures.Add(new

              PolicyFailure(string.Format(Strings.policyViolationMessage,

               csprojFile), this));

      }

    }  

  }

 return failures;

}

 

// This method is called by the policy framework when the plugin is instantiated.

// This gives us an opportunity to capture the pendingCheckin object and register

// for notification of changes in the set of pending changes being checked in.

public void Initialize(IPendingCheckin pendingCheckin)

{

  m_pendingCheckin = pendingCheckin;

  m_pendingCheckin.PendingChanges.CheckedPendingChangesChanged += new

                    EventHandler(PendingChanges_CheckedPendingChangesChanged);

}

 

// This method is called as our policy object is being discarded.  We'll unregister for

// events that were registered in the Initialize() method.

public void Dispose()

{

  m_pendingCheckin.PendingChanges.CheckedPendingChangesChanged -= new

                 EventHandler(PendingChanges_CheckedPendingChangesChanged);

  m_pendingCheckin = null;

}

           

// This is the event handler for changes in the selected source files being checked in.

// As the user checks and unchecks files for checkin from the pending checkin tool window

// or checkin dialog, this event handler will be invoked giving the plugin an opportunity

// to update the policy failures.

private void PendingChanges_CheckedPendingChangesChanged(Object sender, EventArgs e)

{

  OnPolicyStateChanged(Evaluate());

}

 

// This event is subscribed to by the policy framework and gives us a mechanism to

// notify the framework when things happen asynchronously that affect policy compliance.

public event PolicyStateChangedHandler PolicyStateChanged;

 

// This method will notify the policy framework that policy compliance has

// changed and needs to be updated in the UI.

private void OnPolicyStateChanged(PolicyFailure[] failures)

{

  if (PolicyStateChanged != null)

  {

    PolicyStateChanged(this, new PolicyStateChangedEventArgs(failures, this));

  }  

}

 

// This method is called if the user double-clicks on a policy failure in the UI.

// We can handle this as we please, potentially prompting the user to perform

// some activity that would eliminate the policy failure.

public void Activate(PolicyFailure failure)

{

  MessageBox.Show(Strings.policyFailureHelpText);

}

 

// This method is called if the user presses F1 when a policy failure is active in the UI.

// We can handle this as we please, displaying help in whatever format is appropriate.

// For this example, we'll just pop up a dialog.

public void DisplayHelp(PolicyFailure failure)

{

  MessageBox.Show(Strings.policyFailureHelpText,

                                "XML Documentation Policy Help");

}

 

[NonSerialized]

public static readonly PolicyFailure[] m_noFailures = new PolicyFailure[0];

private IPendingCheckin m_pendingCheckin = null;

#endregion

}

}

 

Published Monday, May 23, 2005 7:42 AM by marcelv

Comments

 

TrackBack said:

May 23, 2005 7:49 AM
 

TrackBack said:

May 23, 2005 8:15 PM
 

TrackBack said:

January 17, 2006 8:52 PM
New Comments to this post are disabled
Powered by Community Server, by Telligent Systems