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


