/*
 * 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.
 */

#include <log4cxx/logstring.h>
#include <log4cxx/logger.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/spi/loggerfactory.h>
#include <log4cxx/appender.h>
#include <log4cxx/level.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/synchronized.h>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/helpers/appenderattachableimpl.h>
#include <log4cxx/helpers/exception.h>
#if !defined(LOG4CXX)
    #define LOG4CXX 1
#endif
#include <log4cxx/private/log4cxx_private.h>
#include <log4cxx/helpers/aprinitializer.h>

using namespace log4cxx;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;

IMPLEMENT_LOG4CXX_OBJECT(Logger)

Logger::Logger(Pool& p, const LogString& name1)
    : pool(&p), name(), level(), parent(), resourceBundle(),
      repository(), aai(), SHARED_MUTEX_INIT(mutex, p)
{
    name = name1;
    additive = true;
}

Logger::~Logger()
{
}

void Logger::addRef() const
{
    ObjectImpl::addRef();
}

void Logger::releaseRef() const
{
    ObjectImpl::releaseRef();
}

void Logger::addAppender(const AppenderPtr& newAppender)
{
    log4cxx::spi::LoggerRepository* rep = 0;
    {
        LOCK_W sync(mutex);

        if (aai == 0)
        {
            aai = new AppenderAttachableImpl(*pool);
        }

        aai->addAppender(newAppender);
        rep = repository;
    }

    if (rep != 0)
    {
        rep->fireAddAppenderEvent(this, newAppender);
    }
}


void Logger::callAppenders(const spi::LoggingEventPtr& event, Pool& p) const
{
    int writes = 0;

    for (LoggerPtr logger(const_cast<Logger*>(this));
            logger != 0;
            logger = logger->parent)
    {
        // Protected against simultaneous call to addAppender, removeAppender,...
        LOCK_R sync(logger->mutex);

        if (logger->aai != 0)
        {
            writes += logger->aai->appendLoopOnAppenders(event, p);
        }

        if (!logger->additive)
        {
            break;
        }
    }

    if (writes == 0 && repository != 0)
    {
        repository->emitNoAppenderWarning(const_cast<Logger*>(this));
    }
}

void Logger::closeNestedAppenders()
{
    AppenderList appenders = getAllAppenders();

    for (AppenderList::iterator it = appenders.begin(); it != appenders.end(); ++it)
    {
        (*it)->close();
    }
}


void Logger::forcedLog(const LevelPtr& level1, const std::string& message,
                       const LocationInfo& location) const
{
    Pool p;
    LOG4CXX_DECODE_CHAR(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg, location));
    callAppenders(event, p);
}


void Logger::forcedLog(const LevelPtr& level1, const std::string& message) const
{
    Pool p;
    LOG4CXX_DECODE_CHAR(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg,
                                           LocationInfo::getLocationUnavailable()));
    callAppenders(event, p);
}

void Logger::forcedLogLS(const LevelPtr& level1, const LogString& message,
                         const LocationInfo& location) const
{
    Pool p;
    LoggingEventPtr event(new LoggingEvent(name, level1, message, location));
    callAppenders(event, p);
}


bool Logger::getAdditivity() const
{
    return additive;
}

AppenderList Logger::getAllAppenders() const
{
    LOCK_W sync(mutex);

    if (aai == 0)
    {
        return AppenderList();
    }
    else
    {
        return aai->getAllAppenders();
    }
}

AppenderPtr Logger::getAppender(const LogString& name1) const
{
    LOCK_W sync(mutex);

    if (aai == 0 || name1.empty())
    {
        return 0;
    }

    return aai->getAppender(name1);
}

const LevelPtr& Logger::getEffectiveLevel() const
{
    for (const Logger* l = this; l != 0; l = l->parent)
    {
        if (l->level != 0)
        {
            return l->level;
        }
    }

    throw NullPointerException(LOG4CXX_STR("No level specified for logger or ancestors."));
#if LOG4CXX_RETURN_AFTER_THROW
    return this->level;
#endif
}

LoggerRepositoryPtr Logger::getLoggerRepository() const
{
    return repository;
}

ResourceBundlePtr Logger::getResourceBundle() const
{
    for (LoggerPtr l(const_cast<Logger*>(this)); l != 0; l = l->parent)
    {
        if (l->resourceBundle != 0)
        {
            return l->resourceBundle;
        }
    }

    // It might be the case that there is no resource bundle
    return 0;
}


LogString Logger::getResourceBundleString(const LogString& key) const
{
    ResourceBundlePtr rb = getResourceBundle();

    // This is one of the rare cases where we can use logging in order
    // to report errors from within log4j.
    if (rb == 0)
    {
        return LogString();
    }
    else
    {
        try
        {
            return rb->getString(key);
        }
        catch (MissingResourceException&)
        {
            logLS(Level::getError(), LOG4CXX_STR("No resource is associated with key \"") +
                  key + LOG4CXX_STR("\"."), LocationInfo::getLocationUnavailable());

            return LogString();
        }
    }
}


LoggerPtr Logger::getParent() const
{
    return parent;
}

LevelPtr Logger::getLevel() const
{
    return level;
}


bool Logger::isAttached(const AppenderPtr& appender) const
{
    LOCK_R sync(mutex);

    if (appender == 0 || aai == 0)
    {
        return false;
    }
    else
    {
        return aai->isAttached(appender);
    }
}

bool Logger::isTraceEnabled() const
{
    if (repository == 0 || repository->isDisabled(Level::TRACE_INT))
    {
        return false;
    }

    return getEffectiveLevel()->toInt() <= Level::TRACE_INT;
}

bool Logger::isDebugEnabled() const
{
    if (repository == 0 || repository->isDisabled(Level::DEBUG_INT))
    {
        return false;
    }

    return getEffectiveLevel()->toInt() <= Level::DEBUG_INT;
}

bool Logger::isEnabledFor(const LevelPtr& level1) const
{
    if (repository == 0 || repository->isDisabled(level1->toInt()))
    {
        return false;
    }

    return level1->isGreaterOrEqual(getEffectiveLevel());
}


bool Logger::isInfoEnabled() const
{
    if (repository == 0 || repository->isDisabled(Level::INFO_INT))
    {
        return false;
    }

    return getEffectiveLevel()->toInt() <= Level::INFO_INT;
}

bool Logger::isErrorEnabled() const
{
    if (repository == 0 || repository->isDisabled(Level::ERROR_INT))
    {
        return false;
    }

    return getEffectiveLevel()->toInt() <= Level::ERROR_INT;
}

bool Logger::isWarnEnabled() const
{
    if (repository == 0 || repository->isDisabled(Level::WARN_INT))
    {
        return false;
    }

    return getEffectiveLevel()->toInt() <= Level::WARN_INT;
}

bool Logger::isFatalEnabled() const
{
    if (repository == 0 || repository->isDisabled(Level::FATAL_INT))
    {
        return false;
    }

    return getEffectiveLevel()->toInt() <= Level::FATAL_INT;
}

/*void Logger::l7dlog(const LevelPtr& level, const String& key,
                        const char* file, int line)
{
        if (repository == 0 || repository->isDisabled(level->level))
        {
                return;
        }

        if (level->isGreaterOrEqual(getEffectiveLevel()))
        {
                String msg = getResourceBundleString(key);

                // if message corresponding to 'key' could not be found in the
                // resource bundle, then default to 'key'.
                if (msg.empty())
                {
                        msg = key;
                }

                forcedLog(FQCN, level, msg, file, line);
        }
}*/



void Logger::l7dlog(const LevelPtr& level1, const LogString& key,
                    const LocationInfo& location, const std::vector<LogString>& params) const
{
    if (repository == 0 || repository->isDisabled(level1->toInt()))
    {
        return;
    }

    if (level1->isGreaterOrEqual(getEffectiveLevel()))
    {
        LogString pattern = getResourceBundleString(key);
        LogString msg;

        if (pattern.empty())
        {
            msg = key;
        }
        else
        {
            msg = StringHelper::format(pattern, params);
        }

        forcedLogLS(level1, msg, location);
    }
}

void Logger::l7dlog(const LevelPtr& level1, const std::string& key,
                    const LocationInfo& location) const
{
    LOG4CXX_DECODE_CHAR(lkey, key);

    std::vector<LogString> values(0);
    l7dlog(level1, lkey, location, values);
}

void Logger::l7dlog(const LevelPtr& level1, const std::string& key,
                    const LocationInfo& location, const std::string& val1) const
{
    LOG4CXX_DECODE_CHAR(lkey, key);
    LOG4CXX_DECODE_CHAR(lval1, val1);

    std::vector<LogString> values(1);
    values[0] = lval1;
    l7dlog(level1, lkey, location, values);
}

void Logger::l7dlog(const LevelPtr& level1, const std::string& key,
                    const LocationInfo& location,
                    const std::string& val1, const std::string& val2) const
{
    LOG4CXX_DECODE_CHAR(lkey, key);
    LOG4CXX_DECODE_CHAR(lval1, val1);
    LOG4CXX_DECODE_CHAR(lval2, val2);

    std::vector<LogString> values(2);
    values[0] = lval1;
    values[1] = lval2;
    l7dlog(level1, lkey, location, values);
}

void Logger::l7dlog(const LevelPtr& level1, const std::string& key,
                    const LocationInfo& location,
                    const std::string& val1, const std::string& val2, const std::string& val3) const
{
    LOG4CXX_DECODE_CHAR(lkey, key);
    LOG4CXX_DECODE_CHAR(lval1, val1);
    LOG4CXX_DECODE_CHAR(lval2, val2);
    LOG4CXX_DECODE_CHAR(lval3, val3);

    std::vector<LogString> values(3);
    values[0] = lval1;
    values[1] = lval2;
    values[2] = lval3;
    l7dlog(level1, lkey, location, values);
}



void Logger::removeAllAppenders()
{
    LOCK_W sync(mutex);

    if (aai != 0)
    {
        aai->removeAllAppenders();
        aai = 0;
    }
}

void Logger::removeAppender(const AppenderPtr& appender)
{
    LOCK_W sync(mutex);

    if (appender == 0 || aai == 0)
    {
        return;
    }

    aai->removeAppender(appender);
}

void Logger::removeAppender(const LogString& name1)
{
    LOCK_W sync(mutex);

    if (name1.empty() || aai == 0)
    {
        return;
    }

    aai->removeAppender(name1);
}

void Logger::setAdditivity(bool additive1)
{
    LOCK_W sync(mutex);
    this->additive = additive1;
}

void Logger::setHierarchy(spi::LoggerRepository* repository1)
{
    this->repository = repository1;
}

void Logger::setLevel(const LevelPtr& level1)
{
    this->level = level1;
}



LoggerPtr Logger::getLogger(const std::string& name)
{
    return LogManager::getLogger(name);
}


LoggerPtr Logger::getLogger(const char* const name)
{
    return LogManager::getLogger(name);
}



LoggerPtr Logger::getRootLogger()
{
    return LogManager::getRootLogger();
}

LoggerPtr Logger::getLoggerLS(const LogString& name,
                              const spi::LoggerFactoryPtr& factory)
{
    return LogManager::getLoggerLS(name, factory);
}

void Logger::getName(std::string& rv) const
{
    Transcoder::encode(name, rv);
}


void Logger::trace(const std::string& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg, location);
    }
}


void Logger::trace(const std::string& msg) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg);
    }
}

void Logger::debug(const std::string& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg, location);
    }
}

void Logger::debug(const std::string& msg) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg);
    }
}


void Logger::error(const std::string& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg, location);
    }
}


void Logger::error(const std::string& msg) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg);
    }
}

void Logger::fatal(const std::string& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg, location);
    }
}

void Logger::fatal(const std::string& msg) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg);
    }
}

void Logger::info(const std::string& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg, location);
    }
}

void Logger::info(const std::string& msg) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg);
    }
}

void Logger::log(const LevelPtr& level1, const std::string& message,
                 const log4cxx::spi::LocationInfo& location) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message, location);
    }
}

void Logger::log(const LevelPtr& level1, const std::string& message) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message);
    }
}

void Logger::logLS(const LevelPtr& level1, const LogString& message,
                   const log4cxx::spi::LocationInfo& location) const
{
    if (isEnabledFor(level1))
    {
        forcedLogLS(level1, message, location);
    }
}

void Logger::warn(const std::string& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg, location);
    }
}

void Logger::warn(const std::string& msg) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg);
    }
}

LoggerPtr Logger::getLoggerLS(const LogString& name)
{
    return LogManager::getLoggerLS(name);
}




#if LOG4CXX_WCHAR_T_API
void Logger::forcedLog(const LevelPtr& level1, const std::wstring& message,
                       const LocationInfo& location) const
{
    Pool p;
    LOG4CXX_DECODE_WCHAR(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg, location));
    callAppenders(event, p);
}

void Logger::forcedLog(const LevelPtr& level1, const std::wstring& message) const
{
    Pool p;
    LOG4CXX_DECODE_WCHAR(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg,
                                           LocationInfo::getLocationUnavailable()));
    callAppenders(event, p);
}

void Logger::getName(std::wstring& rv) const
{
    Transcoder::encode(name, rv);
}

LoggerPtr Logger::getLogger(const std::wstring& name)
{
    return LogManager::getLogger(name);
}

LoggerPtr Logger::getLogger(const wchar_t* const name)
{
    return LogManager::getLogger(name);
}

void Logger::trace(const std::wstring& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg, location);
    }
}


void Logger::trace(const std::wstring& msg) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg);
    }
}

void Logger::debug(const std::wstring& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg, location);
    }
}

void Logger::debug(const std::wstring& msg) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg);
    }
}

void Logger::error(const std::wstring& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg, location);
    }
}

void Logger::error(const std::wstring& msg) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg);
    }
}

void Logger::fatal(const std::wstring& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg, location);
    }
}

void Logger::fatal(const std::wstring& msg) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg);
    }
}

void Logger::info(const std::wstring& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg, location);
    }
}

void Logger::info(const std::wstring& msg) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg);
    }
}

void Logger::log(const LevelPtr& level1, const std::wstring& message,
                 const log4cxx::spi::LocationInfo& location) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message, location);
    }
}

void Logger::log(const LevelPtr& level1, const std::wstring& message) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message);
    }
}

void Logger::warn(const std::wstring& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg, location);
    }
}

void Logger::warn(const std::wstring& msg) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg);
    }
}

#endif


#if LOG4CXX_UNICHAR_API || LOG4CXX_CFSTRING_API
void Logger::forcedLog(const LevelPtr& level1, const std::basic_string<UniChar>& message,
                       const LocationInfo& location) const
{
    Pool p;
    LOG4CXX_DECODE_UNICHAR(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg, location));
    callAppenders(event, p);
}

void Logger::forcedLog(const LevelPtr& level1, const std::basic_string<UniChar>& message) const
{
    Pool p;
    LOG4CXX_DECODE_UNICHAR(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg,
                                           LocationInfo::getLocationUnavailable()));
    callAppenders(event, p);
}
#endif

#if LOG4CXX_UNICHAR_API
void Logger::getName(std::basic_string<UniChar>& rv) const
{
    Transcoder::encode(name, rv);
}

LoggerPtr Logger::getLogger(const std::basic_string<UniChar>& name)
{
    return LogManager::getLogger(name);
}

void Logger::trace(const std::basic_string<UniChar>& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg, location);
    }
}


void Logger::trace(const std::basic_string<UniChar>& msg) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg);
    }
}

void Logger::debug(const std::basic_string<UniChar>& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg, location);
    }
}

void Logger::debug(const std::basic_string<UniChar>& msg) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg);
    }
}

void Logger::error(const std::basic_string<UniChar>& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg, location);
    }
}

void Logger::error(const std::basic_string<UniChar>& msg) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg);
    }
}

void Logger::fatal(const std::basic_string<UniChar>& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg, location);
    }
}

void Logger::fatal(const std::basic_string<UniChar>& msg) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg);
    }
}

void Logger::info(const std::basic_string<UniChar>& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg, location);
    }
}

void Logger::info(const std::basic_string<UniChar>& msg) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg);
    }
}

void Logger::log(const LevelPtr& level1, const std::basic_string<UniChar>& message,
                 const log4cxx::spi::LocationInfo& location) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message, location);
    }
}

void Logger::log(const LevelPtr& level1, const std::basic_string<UniChar>& message) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message);
    }
}

void Logger::warn(const std::basic_string<UniChar>& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg, location);
    }
}

void Logger::warn(const std::basic_string<UniChar>& msg) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg);
    }
}

#endif


#if LOG4CXX_CFSTRING_API
void Logger::forcedLog(const LevelPtr& level1, const CFStringRef& message,
                       const LocationInfo& location) const
{
    Pool p;
    LOG4CXX_DECODE_CFSTRING(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg, location));
    callAppenders(event, p);
}

void Logger::forcedLog(const LevelPtr& level1, const CFStringRef& message) const
{
    Pool p;
    LOG4CXX_DECODE_CFSTRING(msg, message);
    LoggingEventPtr event(new LoggingEvent(name, level1, msg,
                                           LocationInfo::getLocationUnavailable()));
    callAppenders(event, p);
}

void Logger::getName(CFStringRef& rv) const
{
    rv = Transcoder::encode(name);
}

LoggerPtr Logger::getLogger(const CFStringRef& name)
{
    return LogManager::getLogger(name);
}

void Logger::trace(const CFStringRef& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg, location);
    }
}


void Logger::trace(const CFStringRef& msg) const
{
    if (isTraceEnabled())
    {
        forcedLog(log4cxx::Level::getTrace(), msg);
    }
}

void Logger::debug(const CFStringRef& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg, location);
    }
}

void Logger::debug(const CFStringRef& msg) const
{
    if (isDebugEnabled())
    {
        forcedLog(log4cxx::Level::getDebug(), msg);
    }
}

void Logger::error(const CFStringRef& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg, location);
    }
}

void Logger::error(const CFStringRef& msg) const
{
    if (isErrorEnabled())
    {
        forcedLog(log4cxx::Level::getError(), msg);
    }
}

void Logger::fatal(const CFStringRef& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg, location);
    }
}

void Logger::fatal(const CFStringRef& msg) const
{
    if (isFatalEnabled())
    {
        forcedLog(log4cxx::Level::getFatal(), msg);
    }
}

void Logger::info(const CFStringRef& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg, location);
    }
}

void Logger::info(const CFStringRef& msg) const
{
    if (isInfoEnabled())
    {
        forcedLog(log4cxx::Level::getInfo(), msg);
    }
}

void Logger::log(const LevelPtr& level1, const CFStringRef& message,
                 const log4cxx::spi::LocationInfo& location) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message, location);
    }
}

void Logger::log(const LevelPtr& level1, const CFStringRef& message) const
{
    if (isEnabledFor(level1))
    {
        forcedLog(level1, message);
    }
}

void Logger::warn(const CFStringRef& msg, const log4cxx::spi::LocationInfo& location) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg, location);
    }
}

void Logger::warn(const CFStringRef& msg) const
{
    if (isWarnEnabled())
    {
        forcedLog(log4cxx::Level::getWarn(), msg);
    }
}

#endif


