#region Apache License
|
//
|
// Licensed to the Apache Software Foundation (ASF) under one or more
|
// contributor license agreements. See the NOTICE file distributed with
|
// this work for additional information regarding copyright ownership.
|
// The ASF licenses this file to you under the Apache License, Version 2.0
|
// (the "License"); you may not use this file except in compliance with
|
// the License. You may obtain a copy of the License at
|
//
|
// http://www.apache.org/licenses/LICENSE-2.0
|
//
|
// Unless required by applicable law or agreed to in writing, software
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// See the License for the specific language governing permissions and
|
// limitations under the License.
|
//
|
#endregion
|
|
using System;
|
using System.Collections;
|
|
using log4net.Repository;
|
|
namespace log4net.Core
|
{
|
#region WrapperCreationHandler
|
|
/// <summary>
|
/// Delegate used to handle creation of new wrappers.
|
/// </summary>
|
/// <param name="logger">The logger to wrap in a wrapper.</param>
|
/// <remarks>
|
/// <para>
|
/// Delegate used to handle creation of new wrappers. This delegate
|
/// is called from the <see cref="WrapperMap.CreateNewWrapperObject"/>
|
/// method to construct the wrapper for the specified logger.
|
/// </para>
|
/// <para>
|
/// The delegate to use is supplied to the <see cref="WrapperMap"/>
|
/// constructor.
|
/// </para>
|
/// </remarks>
|
public delegate ILoggerWrapper WrapperCreationHandler(ILogger logger);
|
|
#endregion WrapperCreationHandler
|
|
/// <summary>
|
/// Maps between logger objects and wrapper objects.
|
/// </summary>
|
/// <remarks>
|
/// <para>
|
/// This class maintains a mapping between <see cref="ILogger"/> objects and
|
/// <see cref="ILoggerWrapper"/> objects. Use the <see cref="GetWrapper"/> method to
|
/// lookup the <see cref="ILoggerWrapper"/> for the specified <see cref="ILogger"/>.
|
/// </para>
|
/// <para>
|
/// New wrapper instances are created by the <see cref="CreateNewWrapperObject"/>
|
/// method. The default behavior is for this method to delegate construction
|
/// of the wrapper to the <see cref="WrapperCreationHandler"/> delegate supplied
|
/// to the constructor. This allows specialization of the behavior without
|
/// requiring subclassing of this type.
|
/// </para>
|
/// </remarks>
|
/// <author>Nicko Cadell</author>
|
/// <author>Gert Driesen</author>
|
public class WrapperMap
|
{
|
#region Public Instance Constructors
|
|
/// <summary>
|
/// Initializes a new instance of the <see cref="WrapperMap" />
|
/// </summary>
|
/// <param name="createWrapperHandler">The handler to use to create the wrapper objects.</param>
|
/// <remarks>
|
/// <para>
|
/// Initializes a new instance of the <see cref="WrapperMap" /> class with
|
/// the specified handler to create the wrapper objects.
|
/// </para>
|
/// </remarks>
|
public WrapperMap(WrapperCreationHandler createWrapperHandler)
|
{
|
m_createWrapperHandler = createWrapperHandler;
|
|
// Create the delegates for the event callbacks
|
m_shutdownHandler = new LoggerRepositoryShutdownEventHandler(ILoggerRepository_Shutdown);
|
}
|
|
#endregion Public Instance Constructors
|
|
#region Public Instance Properties
|
|
/// <summary>
|
/// Gets the wrapper object for the specified logger.
|
/// </summary>
|
/// <returns>The wrapper object for the specified logger</returns>
|
/// <remarks>
|
/// <para>
|
/// If the logger is null then the corresponding wrapper is null.
|
/// </para>
|
/// <para>
|
/// Looks up the wrapper it it has previously been requested and
|
/// returns it. If the wrapper has never been requested before then
|
/// the <see cref="CreateNewWrapperObject"/> virtual method is
|
/// called.
|
/// </para>
|
/// </remarks>
|
virtual public ILoggerWrapper GetWrapper(ILogger logger)
|
{
|
// If the logger is null then the corresponding wrapper is null
|
if (logger == null)
|
{
|
return null;
|
}
|
|
lock(this)
|
{
|
// Lookup hierarchy in map.
|
Hashtable wrappersMap = (Hashtable)m_repositories[logger.Repository];
|
|
if (wrappersMap == null)
|
{
|
// Hierarchy does not exist in map.
|
// Must register with hierarchy
|
|
wrappersMap = new Hashtable();
|
m_repositories[logger.Repository] = wrappersMap;
|
|
// Register for config reset & shutdown on repository
|
logger.Repository.ShutdownEvent += m_shutdownHandler;
|
}
|
|
// Look for the wrapper object in the map
|
ILoggerWrapper wrapperObject = wrappersMap[logger] as ILoggerWrapper;
|
|
if (wrapperObject == null)
|
{
|
// No wrapper object exists for the specified logger
|
|
// Create a new wrapper wrapping the logger
|
wrapperObject = CreateNewWrapperObject(logger);
|
|
// Store wrapper logger in map
|
wrappersMap[logger] = wrapperObject;
|
}
|
|
return wrapperObject;
|
}
|
}
|
|
#endregion Public Instance Properties
|
|
#region Protected Instance Properties
|
|
/// <summary>
|
/// Gets the map of logger repositories.
|
/// </summary>
|
/// <value>
|
/// Map of logger repositories.
|
/// </value>
|
/// <remarks>
|
/// <para>
|
/// Gets the hashtable that is keyed on <see cref="ILoggerRepository"/>. The
|
/// values are hashtables keyed on <see cref="ILogger"/> with the
|
/// value being the corresponding <see cref="ILoggerWrapper"/>.
|
/// </para>
|
/// </remarks>
|
protected Hashtable Repositories
|
{
|
get { return this.m_repositories; }
|
}
|
|
#endregion Protected Instance Properties
|
|
#region Protected Instance Methods
|
|
/// <summary>
|
/// Creates the wrapper object for the specified logger.
|
/// </summary>
|
/// <param name="logger">The logger to wrap in a wrapper.</param>
|
/// <returns>The wrapper object for the logger.</returns>
|
/// <remarks>
|
/// <para>
|
/// This implementation uses the <see cref="WrapperCreationHandler"/>
|
/// passed to the constructor to create the wrapper. This method
|
/// can be overridden in a subclass.
|
/// </para>
|
/// </remarks>
|
virtual protected ILoggerWrapper CreateNewWrapperObject(ILogger logger)
|
{
|
if (m_createWrapperHandler != null)
|
{
|
return m_createWrapperHandler(logger);
|
}
|
return null;
|
}
|
|
/// <summary>
|
/// Called when a monitored repository shutdown event is received.
|
/// </summary>
|
/// <param name="repository">The <see cref="ILoggerRepository"/> that is shutting down</param>
|
/// <remarks>
|
/// <para>
|
/// This method is called when a <see cref="ILoggerRepository"/> that this
|
/// <see cref="WrapperMap"/> is holding loggers for has signaled its shutdown
|
/// event <see cref="ILoggerRepository.ShutdownEvent"/>. The default
|
/// behavior of this method is to release the references to the loggers
|
/// and their wrappers generated for this repository.
|
/// </para>
|
/// </remarks>
|
virtual protected void RepositoryShutdown(ILoggerRepository repository)
|
{
|
lock(this)
|
{
|
// Remove the repository from map
|
m_repositories.Remove(repository);
|
|
// Unhook events from the repository
|
repository.ShutdownEvent -= m_shutdownHandler;
|
}
|
}
|
|
/// <summary>
|
/// Event handler for repository shutdown event.
|
/// </summary>
|
/// <param name="sender">The sender of the event.</param>
|
/// <param name="e">The event args.</param>
|
private void ILoggerRepository_Shutdown(object sender, EventArgs e)
|
{
|
ILoggerRepository repository = sender as ILoggerRepository;
|
if (repository != null)
|
{
|
// Remove all repository from map
|
RepositoryShutdown(repository);
|
}
|
}
|
|
#endregion Protected Instance Methods
|
|
#region Private Instance Variables
|
|
/// <summary>
|
/// Map of logger repositories to hashtables of ILogger to ILoggerWrapper mappings
|
/// </summary>
|
private readonly Hashtable m_repositories = new Hashtable();
|
|
/// <summary>
|
/// The handler to use to create the extension wrapper objects.
|
/// </summary>
|
private readonly WrapperCreationHandler m_createWrapperHandler;
|
|
/// <summary>
|
/// Internal reference to the delegate used to register for repository shutdown events.
|
/// </summary>
|
private readonly LoggerRepositoryShutdownEventHandler m_shutdownHandler;
|
|
#endregion Private Instance Variables
|
}
|
}
|