|
//===============================================================================
// Microsoft Exception Management Application Block for .NET
// http://msdn.microsoft.com/library/en-us/dnbda/html/emab-rm.asp
//
// ExceptionManagerSectionHandler.cs
// This file contains the configuration section handler for the exception
// Management settings.
//
// For more information see the Implementation of the
// ExceptionManagementSectionHandler Class section of the Exception Management
// Application Block Implementation Overview.
//===============================================================================
// Copyright (C) 2000-2001 Microsoft Corporation
// All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
using System;
using System.Resources;
using System.Collections;
using System.Collections.Specialized;
using System.Xml;
using System.Xml.Serialization;
using System.Configuration;
using System.Globalization;
namespace Microsoft.ApplicationBlocks.ExceptionManagement
{
#region Configuration Class Definitions
#region Enum Definitions
/// <summary>
/// Enum containing the mode options for the exceptionManagement tag.
/// </summary>
public enum ExceptionManagementMode
{
/// <summary>The ExceptionManager should not process exceptions.</summary>
Off,
/// <summary>The ExceptionManager should process exceptions. This is the default.</summary>
On
}
/// <summary>
/// Enum containing the mode options for the publisher tag.
/// </summary>
public enum PublisherMode
{
/// <summary>The ExceptionManager should not call the publisher.</summary>
Off,
/// <summary>The ExceptionManager should call the publisher. This is the default.</summary>
On
}
/// <summary>
/// Enum containing the format options for the publisher tag.
/// </summary>
public enum PublisherFormat
{
/// <summary>The ExceptionManager should call the IExceptionPublisher interface of the publisher.
/// This is the default.</summary>
Exception,
/// <summary>The ExceptionManager should call the IExceptionXmlPublisher interface of the publisher.</summary>
Xml
}
#endregion
#region Class Definitions
/// <summary>
/// Class that defines the exception management settings in the config file.
/// </summary>
public class ExceptionManagementSettings
{
private ExceptionManagementMode mode = ExceptionManagementMode.On;
private ArrayList publishers = new ArrayList();
/// <summary>
/// Specifies the whether the exceptionManagement settings are "on" or "off".
/// </summary>
public ExceptionManagementMode Mode
{
get
{
return mode;
}
set
{
mode = value;
}
}
/// <summary>
/// An ArrayList containing all of the PublisherSettings listed in the config file.
/// </summary>
public ArrayList Publishers
{
get
{
return publishers;
}
}
/// <summary>
/// Adds a PublisherSettings to the arraylist of publishers.
/// </summary>
public void AddPublisher(PublisherSettings publisher)
{
publishers.Add(publisher);
}
}
/// <summary>
/// Class that defines the publisher settings within the exception management settings in
/// the config file.
/// </summary>
public class PublisherSettings
{
private PublisherMode mode = PublisherMode.On;
private PublisherFormat exceptionFormat = PublisherFormat.Exception;
private string assemblyName;
private string typeName;
private TypeFilter includeTypes;
private TypeFilter excludeTypes;
private NameValueCollection otherAttributes = new NameValueCollection();
/// <summary>
/// Specifies the whether the exceptionManagement settings are "on" or "off".
/// </summary>
public PublisherMode Mode
{
get
{
return mode;
}
set
{
mode = value;
}
}
/// <summary>
/// Specifies the whether the publisher supports the IExceptionXmlPublisher interface (value is set to "xml")
/// or the publisher supports the IExceptionPublisher interface (value is either left off or set to "exception").
/// </summary>
public PublisherFormat ExceptionFormat
{
get
{
return exceptionFormat;
}
set
{
exceptionFormat = value;
}
}
/// <summary>
/// The assembly name of the publisher component that will be used to invoke the object.
/// </summary>
public string AssemblyName
{
get
{
return assemblyName;
}
set
{
assemblyName = value;
}
}
/// <summary>
/// The type name of the publisher component that will be used to invoke the object.
/// </summary>
public string TypeName
{
get
{
return typeName;
}
set
{
typeName = value;
}
}
/// <summary>
/// A semicolon delimited list of all exception types that the publisher will be invoked for.
/// A "*" can be used to specify all types and is the default value if this is left off.
/// </summary>
public TypeFilter IncludeTypes
{
get
{
return includeTypes;
}
set
{
includeTypes = value;
}
}
/// <summary>
/// A semicolon delimited list of all exception types that the publisher will not be invoked for.
/// A "*" can be used to specify all types. The default is to exclude no types.
/// </summary>
public TypeFilter ExcludeTypes
{
get
{
return excludeTypes;
}
set
{
excludeTypes = value;
}
}
/// <summary>
/// Determines whether the exception type is to be filtered out based on the includes and exclude
/// types specified.
/// </summary>
/// <param name="exceptionType">The Type of the exception to check for filtering.</param>
/// <returns>True is the exception type is to be filtered out, false if it is not filtered out.</returns>
public bool IsExceptionFiltered(Type exceptionType)
{
// If no types are excluded then the exception type is not filtered.
if (excludeTypes == null) return false;
// If the Type is in the Exclude Filter
if (MatchesFilter(exceptionType, excludeTypes))
{
// If the Type is in the Include Filter
if (MatchesFilter(exceptionType, includeTypes))
{
// The Type is not filtered out because it was explicitly Included.
return false;
}
// If the Type is not in the Exclude Filter
else
{
// The Type is filtered because it was Excluded and did not match the Include Filter.
return true;
}
}
// Otherwise it is not Filtered.
else
{
// The Type is not filtered out because it did not match the Exclude Filter.
return false;
}
}
/// <summary>
/// Determines if a type is contained the supplied filter.
/// </summary>
/// <param name="type">The Type to look for</param>
/// <param name="typeFilter">The Filter to test against the Type</param>
/// <returns>true or false</returns>
private bool MatchesFilter(Type type, TypeFilter typeFilter)
{
TypeInfo typeInfo;
// If no filter is provided type does not match the filter.
if (typeFilter == null) return false;
// If all types are accepted in the filter (using the "*") return true.
if (typeFilter.AcceptAllTypes) return true;
// Loop through the types specified in the filter.
for (int i=0;i<typeFilter.Types.Count;i++)
{
typeInfo = (TypeInfo)typeFilter.Types[i];
// If the Type matches this type in the Filter, then return true.
if (typeInfo.ClassType.Equals(type)) return true;
// If the filter type includes SubClasses of itself (it had a "+" before the type in the
// configuration file) AND the Type is a SubClass of the filter type, then return true.
if (typeInfo.IncludeSubClasses == true && typeInfo.ClassType.IsAssignableFrom(type)) return true;
}
// If no matches are found return false.
return false;
}
/// <summary>
/// A collection of any other attributes included within the publisher tag in the config file.
/// </summary>
public NameValueCollection OtherAttributes
{
get
{
return otherAttributes;
}
}
/// <summary>
/// Allows name/value pairs to be added to the Other Attributes collection.
/// </summary>
public void AddOtherAttributes(string name, string value)
{
otherAttributes.Add(name, value);
}
}
/// <summary>
/// TypeFilter class stores contents of the Include and Exclude filters provided in the
/// configuration file
/// </summary>
public class TypeFilter
{
private bool acceptAllTypes = false;
private ArrayList types = new ArrayList();
/// <summary>
/// Indicates if all types should be accepted for a filter
/// </summary>
public bool AcceptAllTypes
{
get
{
return acceptAllTypes;
}
set
{
acceptAllTypes = value;
}
}
/// <summary>
/// Collection of types for the filter
/// </summary>
public ArrayList Types
{
get
{
return types;
}
}
}
/// <summary>
/// TypeInfo class contains information about each type within a TypeFilter
/// </summary>
public class TypeInfo
{
private Type classType;
private bool includeSubClasses = false;
/// <summary>
/// Indicates if subclasses are to be included with the type specified in the Include and Exclude filters
/// </summary>
public bool IncludeSubClasses
{
get
{
return includeSubClasses;
}
set
{
includeSubClasses = value;
}
}
/// <summary>
/// The Type class representing the type specified in the Include and Exclude filters
/// </summary>
public Type ClassType
{
get
{
return classType;
}
set
{
classType = value;
}
}
}
#endregion
#endregion
#region ExceptionManagerSectionHandler
/// <summary>
/// The Configuration Section Handler for the "exceptionManagement" section of the config file.
/// </summary>
public class ExceptionManagerSectionHandler : IConfigurationSectionHandler
{
#region Constructors
/// <summary>
/// The constructor for the ExceptionManagerSectionHandler to initialize the resource file.
/// </summary>
public ExceptionManagerSectionHandler()
{
// Load Resource File for localized text.
resourceManager = new ResourceManager(this.GetType().Namespace + ".ExceptionManagerText",this.GetType().Assembly);
}
#endregion
#region Declare variables
// Member variables.
private readonly static char EXCEPTION_TYPE_DELIMITER = Convert.ToChar(";");
private const string EXCEPTIONMANAGEMENT_MODE = "mode";
private const string PUBLISHER_NODENAME = "publisher";
private const string PUBLISHER_MODE = "mode";
private const string PUBLISHER_ASSEMBLY = "assembly";
private const string PUBLISHER_TYPE = "type";
private const string PUBLISHER_EXCEPTIONFORMAT = "exceptionFormat";
private const string PUBLISHER_INCLUDETYPES = "include";
private const string PUBLISHER_EXCLUDETYPES = "exclude";
private ResourceManager resourceManager;
#endregion
/// <summary>
/// Builds the ExceptionManagementSettings and PublisherSettings structures based on the configuration file.
/// </summary>
/// <param name="parent">Composed from the configuration settings in a corresponding parent configuration section.</param>
/// <param name="configContext">Provides access to the virtual path for which the configuration section handler computes configuration values. Normally this parameter is reserved and is null.</param>
/// <param name="section">The XML node that contains the configuration information to be handled. section provides direct access to the XML contents of the configuration section.</param>
/// <returns>The ExceptionManagementSettings struct built from the configuration settings.</returns>
public object Create(object parent,object configContext,XmlNode section)
{
try
{
ExceptionManagementSettings settings = new ExceptionManagementSettings();
// Exit if there are no configuration settings.
if (section == null) return settings;
XmlNode currentAttribute;
XmlAttributeCollection nodeAttributes = section.Attributes;
// Get the mode attribute.
currentAttribute = nodeAttributes.RemoveNamedItem(EXCEPTIONMANAGEMENT_MODE);
if (currentAttribute != null && currentAttribute.Value.ToUpper(CultureInfo.InvariantCulture) == "OFF")
{
settings.Mode = ExceptionManagementMode.Off;
}
#region Loop through the publisher components and load them into the ExceptionManagementSettings
// Loop through the publisher components and load them into the ExceptionManagementSettings.
PublisherSettings publisherSettings;
foreach(XmlNode node in section.ChildNodes)
{
if (node.Name == PUBLISHER_NODENAME)
{
// Initialize a new PublisherSettings.
publisherSettings = new PublisherSettings();
// Get a collection of all the attributes.
nodeAttributes = node.Attributes;
#region Remove the known attributes and load the struct values
// Remove the mode attribute from the node and set its value in PublisherSettings.
currentAttribute = nodeAttributes.RemoveNamedItem(PUBLISHER_MODE);
if (currentAttribute != null && currentAttribute.Value.ToUpper(CultureInfo.InvariantCulture) == "OFF") publisherSettings.Mode = PublisherMode.Off;
// Remove the assembly attribute from the node and set its value in PublisherSettings.
currentAttribute = nodeAttributes.RemoveNamedItem(PUBLISHER_ASSEMBLY);
if (currentAttribute != null) publisherSettings.AssemblyName = currentAttribute.Value;
// Remove the type attribute from the node and set its value in PublisherSettings.
currentAttribute = nodeAttributes.RemoveNamedItem(PUBLISHER_TYPE);
if (currentAttribute != null) publisherSettings.TypeName = currentAttribute.Value;
// Remove the exceptionFormat attribute from the node and set its value in PublisherSettings.
currentAttribute = nodeAttributes.RemoveNamedItem(PUBLISHER_EXCEPTIONFORMAT);
if (currentAttribute != null && currentAttribute.Value.ToUpper(CultureInfo.InvariantCulture) == "XML") publisherSettings.ExceptionFormat = PublisherFormat.Xml;
// Remove the include attribute from the node and set its value in PublisherSettings.
currentAttribute = nodeAttributes.RemoveNamedItem(PUBLISHER_INCLUDETYPES);
if (currentAttribute != null)
{
publisherSettings.IncludeTypes = LoadTypeFilter(currentAttribute.Value.Split(EXCEPTION_TYPE_DELIMITER));
}
// Remove the exclude attribute from the node and set its value in PublisherSettings.
currentAttribute = nodeAttributes.RemoveNamedItem(PUBLISHER_EXCLUDETYPES);
if (currentAttribute != null)
{
publisherSettings.ExcludeTypes = LoadTypeFilter(currentAttribute.Value.Split(EXCEPTION_TYPE_DELIMITER));
}
#endregion
#region Loop through any other attributes and load them into OtherAttributes
// Loop through any other attributes and load them into OtherAttributes.
for (int i = 0; i < nodeAttributes.Count; i++)
{
publisherSettings.AddOtherAttributes(nodeAttributes.Item(i).Name,nodeAttributes.Item(i).Value);
}
#endregion
// Add the PublisherSettings to the publishers collection.
settings.Publishers.Add(publisherSettings);
}
}
// Remove extra allocated space of the ArrayList of Publishers.
settings.Publishers.TrimToSize();
#endregion
// Return the ExceptionManagementSettings loaded with the values from the config file.
return settings;
}
catch(Exception exc)
{
throw new ConfigurationException(resourceManager.GetString("RES_EXCEPTION_LOADING_CONFIGURATION"), exc, section);
}
}
/// <summary>
/// Creates TypeFilter with type information from the string array of type names.
/// </summary>
/// <param name="rawFilter">String array containing names of types to be included in the filter.</param>
/// <returns>TypeFilter object containing type information.</returns>
private TypeFilter LoadTypeFilter(string[] rawFilter)
{
// Initialize filter
TypeFilter typeFilter = new TypeFilter();
// Verify information was passed in
if (rawFilter != null)
{
TypeInfo exceptionTypeInfo;
// Loop through the string array
for (int i=0;i<rawFilter.GetLength(0);i++)
{
// If the wildcard character "*" exists set the TypeFilter to accept all types.
if (rawFilter[i] == "*")
{
typeFilter.AcceptAllTypes = true;
}
else
{
try
{
if (rawFilter[i].Length > 0)
{
// Create the TypeInfo class
exceptionTypeInfo = new TypeInfo();
// If the string starts with a "+"
if (rawFilter[i].Trim().StartsWith("+"))
{
// Set the TypeInfo class to include subclasses
exceptionTypeInfo.IncludeSubClasses = true;
// Get the Type class from the filter privided.
exceptionTypeInfo.ClassType = Type.GetType(rawFilter[i].Trim().TrimStart(Convert.ToChar("+")),true);
}
else
{
// Set the TypeInfo class not to include subclasses
exceptionTypeInfo.IncludeSubClasses = false;
// Get the Type class from the filter privided.
exceptionTypeInfo.ClassType = Type.GetType(rawFilter[i].Trim(),true);
}
// Add the TypeInfo class to the TypeFilter
typeFilter.Types.Add(exceptionTypeInfo);
}
}
catch(TypeLoadException e)
{
// If the Type could not be created throw a configuration exception.
ExceptionManager.PublishInternalException(new ConfigurationException(resourceManager.GetString("RES_EXCEPTION_LOADING_CONFIGURATION"), e), null);
}
}
}
}
return typeFilter;
}
}
#endregion
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Had worked as analyst programmer for 4 years. Now helping in family business but still involved actively in .Net development whenever there is a free time.