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


&nbsp; // the tag looks like this : <DocumentationFile>binDebugXMLDocumentationPolicy.XML</DocumentationFile>


&nbsp;&nbsp; foreach (string csprojFile in csprojFiles)


&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp; &nbsp;XmlDocument csprojXml = new XmlDocument();


&nbsp;&nbsp;&nbsp; &nbsp;csprojXml.Load(csprojFile);


&nbsp;&nbsp;&nbsp; &nbsp;// if the node is there we know the documentation is enabled


&nbsp;&nbsp;&nbsp; &nbsp;XmlNamespaceManager xmlNS = new XmlNamespaceManager(csprojXml.NameTable);


&nbsp;&nbsp; &nbsp;&nbsp;xmlNS.AddNamespace(“a”,Strings.vsDotNetDefaultNamespace);


&nbsp;&nbsp; &nbsp;&nbsp;XmlNode n = csprojXml.SelectSingleNode(“//a:DocumentationFile”, xmlNS);


&nbsp;&nbsp;&nbsp;&nbsp; if ((n == null) || (n.InnerText.Length== 0))


&nbsp;&nbsp;&nbsp;&nbsp; {


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;failures.Add(new


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PolicyFailure(string.Format(Strings.policyViolationMessage,


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csprojFile), this));


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }


&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;


&nbsp;&nbsp;}


&nbsp;return failures;


}


&nbsp;


// 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)


{


&nbsp; m_pendingCheckin = pendingCheckin;


&nbsp; m_pendingCheckin.PendingChanges.CheckedPendingChangesChanged += new


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventHandler(PendingChanges_CheckedPendingChangesChanged);


}


&nbsp;


// This method is called as our policy object is being discarded.&nbsp; We’ll unregister for


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


public void Dispose()


{


&nbsp; m_pendingCheckin.PendingChanges.CheckedPendingChangesChanged -= new


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EventHandler(PendingChanges_CheckedPendingChangesChanged);


&nbsp;&nbsp;m_pendingCheckin = null;


}


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;


// 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)


{


&nbsp; OnPolicyStateChanged(Evaluate());


}


&nbsp;


// 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;


&nbsp;


// 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)


{


&nbsp; if (PolicyStateChanged != null)


&nbsp; {


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


&nbsp; }&nbsp;&nbsp;


}


&nbsp;


// 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)


{


&nbsp; MessageBox.Show(Strings.policyFailureHelpText);


}


&nbsp;


// 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)


{


&nbsp; MessageBox.Show(Strings.policyFailureHelpText,


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; “XML Documentation Policy Help”);


}


&nbsp;


[NonSerialized]


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


private IPendingCheckin m_pendingCheckin = null;


#endregion


}


}


&nbsp;