PageRenderTime 20ms CodeModel.GetById 14ms app.highlight 4ms RepoModel.GetById 0ms app.codeStats 0ms

/Dependencies/log4net/Core/WrapperMap.cs

https://bitbucket.org/VirtualReality/software-testing
C# | 259 lines | 84 code | 35 blank | 140 comment | 10 complexity | 53e36183ce8d9515f7eb0b072dfc9dec MD5 | raw file
  1#region Apache License
  2//
  3// Licensed to the Apache Software Foundation (ASF) under one or more 
  4// contributor license agreements. See the NOTICE file distributed with
  5// this work for additional information regarding copyright ownership. 
  6// The ASF licenses this file to you under the Apache License, Version 2.0
  7// (the "License"); you may not use this file except in compliance with 
  8// the License. You may obtain a copy of the License at
  9//
 10// http://www.apache.org/licenses/LICENSE-2.0
 11//
 12// Unless required by applicable law or agreed to in writing, software
 13// distributed under the License is distributed on an "AS IS" BASIS,
 14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15// See the License for the specific language governing permissions and
 16// limitations under the License.
 17//
 18#endregion
 19
 20using System;
 21using System.Collections;
 22
 23using log4net.Repository;
 24
 25namespace log4net.Core
 26{
 27	#region WrapperCreationHandler
 28
 29	/// <summary>
 30	/// Delegate used to handle creation of new wrappers.
 31	/// </summary>
 32	/// <param name="logger">The logger to wrap in a wrapper.</param>
 33	/// <remarks>
 34	/// <para>
 35	/// Delegate used to handle creation of new wrappers. This delegate
 36	/// is called from the <see cref="WrapperMap.CreateNewWrapperObject"/>
 37	/// method to construct the wrapper for the specified logger.
 38	/// </para>
 39	/// <para>
 40	/// The delegate to use is supplied to the <see cref="WrapperMap"/>
 41	/// constructor.
 42	/// </para>
 43	/// </remarks>
 44	public delegate ILoggerWrapper WrapperCreationHandler(ILogger logger);
 45
 46	#endregion WrapperCreationHandler
 47
 48	/// <summary>
 49	/// Maps between logger objects and wrapper objects.
 50	/// </summary>
 51	/// <remarks>
 52	/// <para>
 53	/// This class maintains a mapping between <see cref="ILogger"/> objects and
 54	/// <see cref="ILoggerWrapper"/> objects. Use the <see cref="GetWrapper"/> method to 
 55	/// lookup the <see cref="ILoggerWrapper"/> for the specified <see cref="ILogger"/>.
 56	/// </para>
 57	/// <para>
 58	/// New wrapper instances are created by the <see cref="CreateNewWrapperObject"/>
 59	/// method. The default behavior is for this method to delegate construction
 60	/// of the wrapper to the <see cref="WrapperCreationHandler"/> delegate supplied
 61	/// to the constructor. This allows specialization of the behavior without
 62	/// requiring subclassing of this type.
 63	/// </para>
 64	/// </remarks>
 65	/// <author>Nicko Cadell</author>
 66	/// <author>Gert Driesen</author>
 67	public class WrapperMap
 68	{
 69		#region Public Instance Constructors
 70
 71		/// <summary>
 72		/// Initializes a new instance of the <see cref="WrapperMap" />
 73		/// </summary>
 74		/// <param name="createWrapperHandler">The handler to use to create the wrapper objects.</param>
 75		/// <remarks>
 76		/// <para>
 77		/// Initializes a new instance of the <see cref="WrapperMap" /> class with 
 78		/// the specified handler to create the wrapper objects.
 79		/// </para>
 80		/// </remarks>
 81		public WrapperMap(WrapperCreationHandler createWrapperHandler) 
 82		{
 83			m_createWrapperHandler = createWrapperHandler;
 84
 85			// Create the delegates for the event callbacks
 86			m_shutdownHandler = new LoggerRepositoryShutdownEventHandler(ILoggerRepository_Shutdown);
 87		}
 88
 89		#endregion Public Instance Constructors
 90
 91		#region Public Instance Properties
 92
 93		/// <summary>
 94		/// Gets the wrapper object for the specified logger.
 95		/// </summary>
 96		/// <returns>The wrapper object for the specified logger</returns>
 97		/// <remarks>
 98		/// <para>
 99		/// If the logger is null then the corresponding wrapper is null.
100		/// </para>
101		/// <para>
102		/// Looks up the wrapper it it has previously been requested and
103		/// returns it. If the wrapper has never been requested before then
104		/// the <see cref="CreateNewWrapperObject"/> virtual method is
105		/// called.
106		/// </para>
107		/// </remarks>
108		virtual public ILoggerWrapper GetWrapper(ILogger logger)
109		{
110			// If the logger is null then the corresponding wrapper is null
111			if (logger == null)
112			{
113				return null;
114			}
115
116			lock(this)
117			{
118				// Lookup hierarchy in map.
119				Hashtable wrappersMap = (Hashtable)m_repositories[logger.Repository];
120
121				if (wrappersMap == null)
122				{
123					// Hierarchy does not exist in map.
124					// Must register with hierarchy
125
126					wrappersMap = new Hashtable();
127					m_repositories[logger.Repository] = wrappersMap;
128
129					// Register for config reset & shutdown on repository
130					logger.Repository.ShutdownEvent += m_shutdownHandler;
131				}
132
133				// Look for the wrapper object in the map
134				ILoggerWrapper wrapperObject = wrappersMap[logger] as ILoggerWrapper;
135
136				if (wrapperObject == null)
137				{
138					// No wrapper object exists for the specified logger
139
140					// Create a new wrapper wrapping the logger
141					wrapperObject = CreateNewWrapperObject(logger);
142					
143					// Store wrapper logger in map
144					wrappersMap[logger] = wrapperObject;
145				}
146
147				return wrapperObject;
148			}
149		}
150
151		#endregion Public Instance Properties
152
153		#region Protected Instance Properties
154
155		/// <summary>
156		/// Gets the map of logger repositories.
157		/// </summary>
158		/// <value>
159		/// Map of logger repositories.
160		/// </value>
161		/// <remarks>
162		/// <para>
163		/// Gets the hashtable that is keyed on <see cref="ILoggerRepository"/>. The
164		/// values are hashtables keyed on <see cref="ILogger"/> with the
165		/// value being the corresponding <see cref="ILoggerWrapper"/>.
166		/// </para>
167		/// </remarks>
168		protected Hashtable Repositories 
169		{
170			get { return this.m_repositories; }
171		}
172
173		#endregion Protected Instance Properties
174
175		#region Protected Instance Methods
176
177		/// <summary>
178		/// Creates the wrapper object for the specified logger.
179		/// </summary>
180		/// <param name="logger">The logger to wrap in a wrapper.</param>
181		/// <returns>The wrapper object for the logger.</returns>
182		/// <remarks>
183		/// <para>
184		/// This implementation uses the <see cref="WrapperCreationHandler"/>
185		/// passed to the constructor to create the wrapper. This method
186		/// can be overridden in a subclass.
187		/// </para>
188		/// </remarks>
189		virtual protected ILoggerWrapper CreateNewWrapperObject(ILogger logger)
190		{
191			if (m_createWrapperHandler != null)
192			{
193				return m_createWrapperHandler(logger);
194			}
195			return null;
196		}
197
198		/// <summary>
199		/// Called when a monitored repository shutdown event is received.
200		/// </summary>
201		/// <param name="repository">The <see cref="ILoggerRepository"/> that is shutting down</param>
202		/// <remarks>
203		/// <para>
204		/// This method is called when a <see cref="ILoggerRepository"/> that this
205		/// <see cref="WrapperMap"/> is holding loggers for has signaled its shutdown
206		/// event <see cref="ILoggerRepository.ShutdownEvent"/>. The default
207		/// behavior of this method is to release the references to the loggers
208		/// and their wrappers generated for this repository.
209		/// </para>
210		/// </remarks>
211		virtual protected void RepositoryShutdown(ILoggerRepository repository)
212		{
213			lock(this)
214			{
215				// Remove the repository from map
216				m_repositories.Remove(repository);
217
218				// Unhook events from the repository
219				repository.ShutdownEvent -= m_shutdownHandler;
220			}
221		}
222
223		/// <summary>
224		/// Event handler for repository shutdown event.
225		/// </summary>
226		/// <param name="sender">The sender of the event.</param>
227		/// <param name="e">The event args.</param>
228		private void ILoggerRepository_Shutdown(object sender, EventArgs e)
229		{
230			ILoggerRepository repository = sender as ILoggerRepository;
231			if (repository != null)
232			{
233				// Remove all repository from map
234				RepositoryShutdown(repository);
235			}
236		}
237
238		#endregion Protected Instance Methods
239
240		#region Private Instance Variables
241
242		/// <summary>
243		/// Map of logger repositories to hashtables of ILogger to ILoggerWrapper mappings
244		/// </summary>
245		private readonly Hashtable m_repositories = new Hashtable();
246
247		/// <summary>
248		/// The handler to use to create the extension wrapper objects.
249		/// </summary>
250		private readonly WrapperCreationHandler m_createWrapperHandler;
251
252		/// <summary>
253		/// Internal reference to the delegate used to register for repository shutdown events.
254		/// </summary>
255		private readonly LoggerRepositoryShutdownEventHandler m_shutdownHandler;
256 
257		#endregion Private Instance Variables
258	}
259}