⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hierarchy.cs

📁 网上书店系统
💻 CS
📖 第 1 页 / 共 3 页
字号:
					logger = factory.CreateLogger(name);
					logger.Hierarchy = this; 
					m_ht[key] = logger;
					UpdateChildren(nodeProvisionNode, logger);
					UpdateParents(logger);	
					OnLoggerCreationEvent(logger);
					return logger;
				}

				// It should be impossible to arrive here but let's keep the compiler happy.
				return null;
			}
		}

		#endregion Public Instance Methods

		#region Protected Instance Methods

		/// <summary>
		/// Sends a logger creation event to all registered listeners
		/// </summary>
		/// <param name="logger">The newly created logger</param>
		/// <remarks>
		/// Raises the logger creation event.
		/// </remarks>
		protected virtual void OnLoggerCreationEvent(Logger logger) 
		{
			LoggerCreationEventHandler handler = m_loggerCreatedEvent;
			if (handler != null)
			{
				handler(this, new LoggerCreationEventArgs(logger));
			}
		}

		#endregion Protected Instance Methods

		#region Private Instance Methods

		/// <summary>
		/// Updates all the parents of the specified logger
		/// </summary>
		/// <param name="log">The logger to update the parents for</param>
		/// <remarks>
		/// <para>
		/// This method loops through all the <i>potential</i> parents of
		/// <paramref name="log"/>. There 3 possible cases:
		/// </para>
		/// <list type="number">
		///		<item>
		///			<term>No entry for the potential parent of <paramref name="log"/> exists</term>
		///			<description>
		///			We create a ProvisionNode for this potential 
		///			parent and insert <paramref name="log"/> in that provision node.
		///			</description>
		///		</item>
		///		<item>
		///			<term>The entry is of type Logger for the potential parent.</term>
		///			<description>
		///			The entry is <paramref name="log"/>'s nearest existing parent. We 
		///			update <paramref name="log"/>'s parent field with this entry. We also break from 
		///			he loop because updating our parent's parent is our parent's 
		///			responsibility.
		///			</description>
		///		</item>
		///		<item>
		///			<term>The entry is of type ProvisionNode for this potential parent.</term>
		///			<description>
		///			We add <paramref name="log"/> to the list of children for this 
		///			potential parent.
		///			</description>
		///		</item>
		/// </list>
		/// </remarks>
		private void UpdateParents(Logger log) 
		{
			string name = log.Name;
			int length = name.Length;
			bool parentFound = false;
	
			// if name = "w.x.y.z", loop through "w.x.y", "w.x" and "w", but not "w.x.y.z" 
			for(int i = name.LastIndexOf('.', length-1); i >= 0; i = name.LastIndexOf('.', i-1))  
			{
				string substr = name.Substring(0, i);

				LoggerKey key = new LoggerKey(substr); // simple constructor
				Object node = m_ht[key];
				// Create a provision node for a future parent.
				if (node == null) 
				{
					ProvisionNode pn = new ProvisionNode(log);
					m_ht[key] = pn;
				} 
				else
				{
					Logger nodeLogger = node as Logger;
					if (nodeLogger != null)
					{
						parentFound = true;
						log.Parent = nodeLogger;
						break; // no need to update the ancestors of the closest ancestor
					}
					else
					{
						ProvisionNode nodeProvisionNode = node as ProvisionNode;
						if (nodeProvisionNode != null)
						{
							nodeProvisionNode.Add(log);
						}
						else
						{
							LogLog.Error("Hierarchy: Unexpected object type ["+node.GetType()+"] in ht.", new LogException());
						}
					} 
				} 
			}

			// If we could not find any existing parents, then link with root.
			if (!parentFound) 
			{
				log.Parent = this.Root;
			}
		}

		/// <summary>
		/// Replace a <see cref="ProvisionNode"/> with a <see cref="Logger"/> in the hierarchy.
		/// </summary>
		/// <param name="pn"></param>
		/// <param name="log"></param>
		/// <remarks>
		/// <para>
		/// We update the links for all the children that placed themselves
		/// in the provision node 'pn'. The second argument 'log' is a
		/// reference for the newly created Logger, parent of all the
		/// children in 'pn'.
		/// </para>
		/// <para>
		/// We loop on all the children 'c' in 'pn'.
		/// </para>
		/// <para>
		/// If the child 'c' has been already linked to a child of
		/// 'log' then there is no need to update 'c'.
		/// </para>
		/// <para>
		/// Otherwise, we set log's parent field to c's parent and set
		/// c's parent field to log.
		/// </para>
		/// </remarks>
		private void UpdateChildren(ProvisionNode pn, Logger log) 
		{
			for(int i = 0; i < pn.Count; i++) 
			{
				Logger childLogger = (Logger)pn[i];

				// Unless this child already points to a correct (lower) parent,
				// make log.Parent point to childLogger.Parent and childLogger.Parent to log.
				if (!childLogger.Parent.Name.StartsWith(log.Name)) 
				{
					log.Parent = childLogger.Parent;
					childLogger.Parent = log;	  
				}
			}
		}

		/// <summary>
		/// Define or redefine a Level using the values in the <see cref="LevelEntry"/> argument
		/// </summary>
		/// <param name="levelEntry">the level values</param>
		/// <remarks>
		/// <para>
		/// Define or redefine a Level using the values in the <see cref="LevelEntry"/> argument
		/// </para>
		/// <para>
		/// Supports setting levels via the configuration file.
		/// </para>
		/// </remarks>
		internal void AddLevel(LevelEntry levelEntry)
		{
			if (levelEntry == null) throw new ArgumentNullException("levelEntry");
			if (levelEntry.Name == null) throw new ArgumentNullException("levelEntry.Name");

			// Lookup replacement value
			if (levelEntry.Value == -1)
			{
				Level previousLevel = LevelMap[levelEntry.Name];
				if (previousLevel == null)
				{
					throw new InvalidOperationException("Cannot redefine level ["+levelEntry.Name+"] because it is not defined in the LevelMap. To define the level supply the level value.");
				}

				levelEntry.Value = previousLevel.Value;
			}

			LevelMap.Add(levelEntry.Name, levelEntry.Value, levelEntry.DisplayName);
		}

		/// <summary>
		/// A class to hold the value, name and display name for a level
		/// </summary>
		/// <remarks>
		/// <para>
		/// A class to hold the value, name and display name for a level
		/// </para>
		/// </remarks>
		internal class LevelEntry
		{
			private int m_levelValue = -1;
			private string m_levelName = null;
			private string m_levelDisplayName = null;

			/// <summary>
			/// Value of the level
			/// </summary>
			/// <remarks>
			/// <para>
			/// If the value is not set (defaults to -1) the value will be looked
			/// up for the current level with the same name.
			/// </para>
			/// </remarks>
			public int Value
			{
				get { return m_levelValue; }
				set { m_levelValue = value; }
			}

			/// <summary>
			/// Name of the level
			/// </summary>
			/// <value>
			/// The name of the level
			/// </value>
			/// <remarks>
			/// <para>
			/// The name of the level.
			/// </para>
			/// </remarks>
			public string Name
			{
				get { return m_levelName; }
				set { m_levelName = value; }
			}

			/// <summary>
			/// Display name for the level
			/// </summary>
			/// <value>
			/// The display name of the level
			/// </value>
			/// <remarks>
			/// <para>
			/// The display name of the level.
			/// </para>
			/// </remarks>
			public string DisplayName
			{
				get { return m_levelDisplayName; }
				set { m_levelDisplayName = value; }
			}

			/// <summary>
			/// Override <c>Object.ToString</c> to return sensible debug info
			/// </summary>
			/// <returns>string info about this object</returns>
			public override string ToString()
			{
				return "LevelEntry(Value="+m_levelValue+", Name="+m_levelName+", DisplayName="+m_levelDisplayName+")";
			}
		}

		/// <summary>
		/// Set a Property using the values in the <see cref="LevelEntry"/> argument
		/// </summary>
		/// <param name="propertyEntry">the property value</param>
		/// <remarks>
		/// <para>
		/// Set a Property using the values in the <see cref="LevelEntry"/> argument.
		/// </para>
		/// <para>
		/// Supports setting property values via the configuration file.
		/// </para>
		/// </remarks>
		internal void AddProperty(PropertyEntry propertyEntry)
		{
			if (propertyEntry == null) throw new ArgumentNullException("propertyEntry");
			if (propertyEntry.Key == null) throw new ArgumentNullException("propertyEntry.Key");

			Properties[propertyEntry.Key] = propertyEntry.Value;
		}

		/// <summary>
		/// A class to hold the key and data for a property set in the config file
		/// </summary>
		/// <remarks>
		/// <para>
		/// A class to hold the key and data for a property set in the config file
		/// </para>
		/// </remarks>
		internal class PropertyEntry
		{
			private string m_key = null;
			private object m_value = null;

			/// <summary>
			/// Property Key
			/// </summary>
			/// <value>
			/// Property Key
			/// </value>
			/// <remarks>
			/// <para>
			/// Property Key.
			/// </para>
			/// </remarks>
			public string Key
			{
				get { return m_key; }
				set { m_key = value; }
			}

			/// <summary>
			/// Property Value
			/// </summary>
			/// <value>
			/// Property Value
			/// </value>
			/// <remarks>
			/// <para>
			/// Property Value.
			/// </para>
			/// </remarks>
			public object Value
			{
				get { return m_value; }
				set { m_value = value; }
			}

			/// <summary>
			/// Override <c>Object.ToString</c> to return sensible debug info
			/// </summary>
			/// <returns>string info about this object</returns>
			public override string ToString()
			{
				return "PropertyEntry(Key="+m_key+", Value="+m_value+")";
			}
		}

		#endregion Private Instance Methods

		#region Private Instance Fields

		private ILoggerFactory m_defaultFactory;

		private System.Collections.Hashtable m_ht;
		private Logger m_root;
  
		private bool m_emittedNoAppenderWarning = false;
		private event LoggerCreationEventHandler m_loggerCreatedEvent;

		#endregion Private Instance Fields
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -