using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
namespace Company.Moss.FeatureReceiver
{
class CustomFeatureReceiver : SPFeatureReceiver
{
protected SPFeatureReceiverProperties _properties;
#region base overrides
public override void FeatureInstalled(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
{
//throw new Exception("The method or operation is not implemented.");
}
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
//This is where the WebConfigChanges file should be
string fileLoc = properties.Definition.RootDirectory + "\\WebConfigChanges.xml";
//Check to see if a WebConfigChanges.xml file exists. If yes, we have work to do
if (System.IO.File.Exists(fileLoc))
{
//Grab the properties
_properties = properties;
this.ProcessChanges(fileLoc, false);
}
}
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
//This is where the WebConfigChanges file should be
string fileLoc = properties.Definition.RootDirectory + "\\WebConfigChanges.xml";
//Check to see if a WebConfigChanges.xml file exists. If yes, we have work to do
if (System.IO.File.Exists(fileLoc))
{
//Grab the properties
_properties = properties;
this.ProcessChanges(fileLoc, true);
}
}
#endregion
private void ProcessChanges(string FileLocation, bool removeModification)
{
string xPathLocation;
string elementName;
Dictionary<string, string> attributes = new Dictionary<string, string>();
using (XmlReader reader = XmlReader.Create(FileLocation))
{
//Loop through all of the changes
while(reader.ReadToFollowing("WebConfigChange"))
{
//Clean out any attributes from past iterations
attributes.Clear();
xPathLocation = reader.GetAttribute("XPathLocation");
elementName = reader.GetAttribute("ElementName");
//Make sure we have at least a path and element
if (xPathLocation == null || elementName == null)
throw new Exception("WebConfigChange missing required XPathLocation or ElementName attributes");
//Get the Attributes to apply
if (reader.ReadToDescendant("Attribute"))
{
do
{
attributes.Add(reader.GetAttribute("Name"), reader.GetAttribute("Value"));
} while (reader.ReadToNextSibling("Attribute"));
}
//Do the update
UpdateWebConfig(xPathLocation, elementName, attributes, removeModification);
}
}
}
private void UpdateWebConfig(string XPathLocation, string ElementName,
Dictionary<string, string> Attributes, bool removeModification)
{
try
{
SPWebApplication webApp = null;
//Get the web app
//First check if it was deployed to a Site Collection
SPSiteCollection siteCol = _properties.Feature.Parent as SPSiteCollection;
if (siteCol == null)
{
//Check if it was deployed to a site
SPSite site = _properties.Feature.Parent as SPSite;
if (site == null)
{
//Check if it was deployed to a Site
SPWeb web = _properties.Feature.Parent as SPWeb;
if (web != null)
webApp = web.Site.WebApplication;
}
else
webApp = SPWebApplication.Lookup(new Uri(site.Url));
}
else
webApp = siteCol.WebApplication;
if (webApp != null)
{
SPWebConfigModification modification =
new SPWebConfigModification(ElementName + CreateAttributeString(Attributes), XPathLocation);
modification.Owner = "Company.Moss.FeatureReceiver.CustomFeatureReceiver";
modification.Sequence = 0;
modification.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
modification.Value =
string.Format(CultureInfo.InvariantCulture,
CreateModificationValueString(ElementName, Attributes),
CreateModificationValueArgs(Attributes));
if (removeModification)
webApp.WebConfigModifications.Remove(modification);
else
webApp.WebConfigModifications.Add(modification);
SPFarm.Local.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
}
else
throw new ApplicationException("Could not locate a web application");
}
catch (Exception ex)
{
System.Diagnostics.EventLog el = new System.Diagnostics.EventLog();
el.Source = "WebConfigFeature";
el.WriteEntry(ex.Message);
}
}
/// <summary>
/// Accepts a dictionary object with all of the attributes for the web modification and
/// creates a string representing the attribute values which can be used when creating
/// the SPWebConfigModification object.
/// </summary>
/// <param name="Attributes"></param>
/// <returns></returns>
private string CreateAttributeString(Dictionary<string, string> Attributes)
{
//Create a string that looks like this (no line breaks):
//[@Assembly=\"Company.Moss.Activities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9eed2245513232a4\"]
//[@Namespace=\"Company.Moss.Activities\"]
//[@TypeName=\"*\"][@Authorized=\"True\"]
string result = "";
//Check if there are attributes
if (Attributes.Count > 0)
{
foreach (KeyValuePair<string, string> kvp in Attributes)
{
result += "[@" + kvp.Key + "=\"" + kvp.Value + "\"]";
}
}
return result;
}
private string CreateModificationValueString(string ElementName, Dictionary<string, string> Attributes)
{
//Create a string that looks like this:
//"<authorizedType Assembly=\"{0}\" Namespace=\"{1}\" TypeName=\"{2}\" Authorized=\"{3}\"/>"
string result = "<" + ElementName;
//Check if there are attributes (Kind of silly if there aren't!)
if (Attributes.Count > 0)
{
int i = 0;
foreach (string key in Attributes.Keys)
{
result += " " + key + "=\"{" + i.ToString() + "}\"";
i++;
}
}
result += " />";
return result;
}
private object[] CreateModificationValueArgs(Dictionary<string, string> Attributes)
{
//Create an object that looks like this:
//"Company.Moss.Activities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9eed2245513232a4", "Company.Moss.Activities", "*", "True"
object[] result = new object[Attributes.Count];
int i = 0;
foreach(string value in Attributes.Values)
{
result[i] = value;
i++;
}
return result;
}
}
}