#region Copyright & License
//
// Copyright 2001-2005 The Apache Software Foundation
//
// Licensed 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 System.Reflection;
using log4net.Appender;
using log4net.Util;
using log4net.Repository;
namespace log4net.Core
{
///
/// The implementation of the interface suitable
/// for use with the compact framework
///
///
///
/// This implementation is a simple
/// mapping between repository name and
/// object.
///
///
/// The .NET Compact Framework 1.0 does not support retrieving assembly
/// level attributes therefore unlike the DefaultRepositorySelector
/// this selector does not examine the calling assembly for attributes.
///
///
/// Nicko Cadell
public class CompactRepositorySelector : IRepositorySelector
{
#region Member Variables
private const string DefaultRepositoryName = "log4net-default-repository";
private readonly Hashtable m_name2repositoryMap = new Hashtable();
private readonly Type m_defaultRepositoryType;
private event LoggerRepositoryCreationEventHandler m_loggerRepositoryCreatedEvent;
#endregion
#region Constructors
///
/// Create a new repository selector
///
/// the type of the repositories to create, must implement
///
///
/// Create an new compact repository selector.
/// The default type for repositories must be specified,
/// an appropriate value would be .
///
///
/// throw if is null
/// throw if does not implement
public CompactRepositorySelector(Type defaultRepositoryType)
{
if (defaultRepositoryType == null)
{
throw new ArgumentNullException("defaultRepositoryType");
}
// Check that the type is a repository
if (! (typeof(ILoggerRepository).IsAssignableFrom(defaultRepositoryType)) )
{
throw log4net.Util.SystemInfo.CreateArgumentOutOfRangeException("defaultRepositoryType", (object)defaultRepositoryType, "Parameter: defaultRepositoryType, Value: ["+defaultRepositoryType+"] out of range. Argument must implement the ILoggerRepository interface");
}
m_defaultRepositoryType = defaultRepositoryType;
LogLog.Debug("CompactRepositorySelector: defaultRepositoryType ["+m_defaultRepositoryType+"]");
}
#endregion
#region Implementation of IRepositorySelector
///
/// Get the for the specified assembly
///
/// not used
/// The default
///
///
/// The argument is not used. This selector does not create a
/// separate repository for each assembly.
///
///
/// As a named repository is not specified the default repository is
/// returned. The default repository is named log4net-default-repository.
///
///
public ILoggerRepository GetRepository(Assembly assembly)
{
return CreateRepository(assembly, m_defaultRepositoryType);
}
///
/// Get the named
///
/// the name of the repository to lookup
/// The named
///
///
/// Get the named . The default
/// repository is log4net-default-repository. Other repositories
/// must be created using the .
/// If the named repository does not exist an exception is thrown.
///
///
/// throw if is null
/// throw if the does not exist
public ILoggerRepository GetRepository(string repositoryName)
{
if (repositoryName == null)
{
throw new ArgumentNullException("repositoryName");
}
lock(this)
{
// Lookup in map
ILoggerRepository rep = m_name2repositoryMap[repositoryName] as ILoggerRepository;
if (rep == null)
{
throw new LogException("Repository ["+repositoryName+"] is NOT defined.");
}
return rep;
}
}
///
/// Create a new repository for the assembly specified
///
/// not used
/// the type of repository to create, must implement
/// the repository created
///
///
/// The argument is not used. This selector does not create a
/// separate repository for each assembly.
///
///
/// If the is null then the
/// default repository type specified to the constructor is used.
///
///
/// As a named repository is not specified the default repository is
/// returned. The default repository is named log4net-default-repository.
///
///
public ILoggerRepository CreateRepository(Assembly assembly, Type repositoryType)
{
// If the type is not set then use the default type
if (repositoryType == null)
{
repositoryType = m_defaultRepositoryType;
}
lock(this)
{
// This method should not throw if the default repository already exists.
// First check that the repository does not exist
ILoggerRepository rep = m_name2repositoryMap[DefaultRepositoryName] as ILoggerRepository;
if (rep == null)
{
// Must create the repository
rep = CreateRepository(DefaultRepositoryName, repositoryType);
}
return rep;
}
}
///
/// Create a new repository for the repository specified
///
/// the repository to associate with the
/// the type of repository to create, must implement .
/// If this param is null then the default repository type is used.
/// the repository created
///
///
/// The created will be associated with the repository
/// specified such that a call to with the
/// same repository specified will return the same repository instance.
///
///
/// If the named repository already exists an exception will be thrown.
///
///
/// If is null then the default
/// repository type specified to the constructor is used.
///
///
/// throw if is null
/// throw if the already exists
public ILoggerRepository CreateRepository(string repositoryName, Type repositoryType)
{
if (repositoryName == null)
{
throw new ArgumentNullException("repositoryName");
}
// If the type is not set then use the default type
if (repositoryType == null)
{
repositoryType = m_defaultRepositoryType;
}
lock(this)
{
ILoggerRepository rep = null;
// First check that the repository does not exist
rep = m_name2repositoryMap[repositoryName] as ILoggerRepository;
if (rep != null)
{
throw new LogException("Repository ["+repositoryName+"] is already defined. Repositories cannot be redefined.");
}
else
{
LogLog.Debug("DefaultRepositorySelector: Creating repository ["+repositoryName+"] using type ["+repositoryType+"]");
// Call the no arg constructor for the repositoryType
rep = (ILoggerRepository)Activator.CreateInstance(repositoryType);
// Set the name of the repository
rep.Name = repositoryName;
// Store in map
m_name2repositoryMap[repositoryName] = rep;
// Notify listeners that the repository has been created
OnLoggerRepositoryCreatedEvent(rep);
}
return rep;
}
}
///
/// Test if a named repository exists
///
/// the named repository to check
/// true if the repository exists
///
///
/// Test if a named repository exists. Use
/// to create a new repository and to retrieve
/// a repository.
///
///
public bool ExistsRepository(string repositoryName)
{
lock(this)
{
return m_name2repositoryMap.ContainsKey(repositoryName);
}
}
///
/// Gets a list of objects
///
/// an array of all known objects
///
///
/// Gets an array of all of the repositories created by this selector.
///
///
public ILoggerRepository[] GetAllRepositories()
{
lock(this)
{
ICollection reps = m_name2repositoryMap.Values;
ILoggerRepository[] all = new ILoggerRepository[reps.Count];
reps.CopyTo(all, 0);
return all;
}
}
#endregion
///
/// Event to notify that a logger repository has been created.
///
///
/// Event to notify that a logger repository has been created.
///
///
///
/// Event raised when a new repository is created.
/// The event source will be this selector. The event args will
/// be a which
/// holds the newly created .
///
///
public event LoggerRepositoryCreationEventHandler LoggerRepositoryCreatedEvent
{
add { m_loggerRepositoryCreatedEvent += value; }
remove { m_loggerRepositoryCreatedEvent -= value; }
}
///
/// Notify the registered listeners that the repository has been created
///
/// The repository that has been created
///
///
/// Raises the LoggerRepositoryCreatedEvent
/// event.
///
///
protected virtual void OnLoggerRepositoryCreatedEvent(ILoggerRepository repository)
{
LoggerRepositoryCreationEventHandler handler = m_loggerRepositoryCreatedEvent;
if (handler != null)
{
handler(this, new LoggerRepositoryCreationEventArgs(repository));
}
}
}
}