/*
 * 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/xml/domconfigurator.h>
#include <log4cxx/appender.h>
#include <log4cxx/layout.h>
#include <log4cxx/logger.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/level.h>
#include <log4cxx/spi/filter.h>
#include <log4cxx/helpers/loglog.h>
#include <log4cxx/helpers/stringhelper.h>
#include <log4cxx/helpers/loader.h>
#include <log4cxx/helpers/optionconverter.h>
#include <log4cxx/config/propertysetter.h>
#include <log4cxx/spi/errorhandler.h>
#include <log4cxx/spi/loggerfactory.h>
#include <log4cxx/defaultloggerfactory.h>
#include <log4cxx/helpers/filewatchdog.h>
#include <log4cxx/helpers/synchronized.h>
#include <log4cxx/spi/loggerrepository.h>
#include <log4cxx/spi/loggingevent.h>
#include <log4cxx/helpers/pool.h>
#include <sstream>
#include <log4cxx/helpers/transcoder.h>
#include <log4cxx/rolling/rollingfileappender.h>
#include <log4cxx/rolling/filterbasedtriggeringpolicy.h>
#include <apr_xml.h>
#include <log4cxx/helpers/bytebuffer.h>
#include <log4cxx/helpers/charsetdecoder.h>
#include <log4cxx/net/smtpappender.h>
#include <log4cxx/helpers/messagebuffer.h>

#define LOG4CXX 1
#include <log4cxx/helpers/aprinitializer.h>

using namespace log4cxx;
using namespace log4cxx::xml;
using namespace log4cxx::helpers;
using namespace log4cxx::spi;
using namespace log4cxx::config;
using namespace log4cxx::rolling;


#if APR_HAS_THREADS
namespace log4cxx
{
namespace xml
{
class XMLWatchdog  : public FileWatchdog
{
    public:
        XMLWatchdog(const File& filename) : FileWatchdog(filename)
        {
        }

        /**
        Call DOMConfigurator#doConfigure with the
        <code>filename</code> to reconfigure log4cxx.
        */
        void doOnChange()
        {
            DOMConfigurator().doConfigure(file,
                                          LogManager::getLoggerRepository());
        }
};
}
}
XMLWatchdog* DOMConfigurator::xdog = NULL;
#endif


IMPLEMENT_LOG4CXX_OBJECT(DOMConfigurator)

#define CONFIGURATION_TAG "log4j:configuration"
#define OLD_CONFIGURATION_TAG "configuration"
#define APPENDER_TAG "appender"
#define APPENDER_REF_TAG "appender-ref"
#define PARAM_TAG "param"
#define LAYOUT_TAG "layout"
#define ROLLING_POLICY_TAG "rollingPolicy"
#define TRIGGERING_POLICY_TAG "triggeringPolicy"
#define CATEGORY "category"
#define LOGGER "logger"
#define LOGGER_REF "logger-ref"
#define CATEGORY_FACTORY_TAG "categoryFactory"
#define NAME_ATTR "name"
#define CLASS_ATTR "class"
#define VALUE_ATTR "value"
#define ROOT_TAG "root"
#define ROOT_REF "root-ref"
#define LEVEL_TAG "level"
#define PRIORITY_TAG "priority"
#define FILTER_TAG "filter"
#define ERROR_HANDLER_TAG "errorHandler"
#define REF_ATTR "ref"
#define ADDITIVITY_ATTR "additivity"
#define THRESHOLD_ATTR "threshold"
#define STRINGSTREAM_ATTR "stringstream"
#define CONFIG_DEBUG_ATTR "configDebug"
#define INTERNAL_DEBUG_ATTR "debug"

DOMConfigurator::DOMConfigurator()
    : props(), repository()
{
}

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

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

/**
Used internally to parse appenders by IDREF name.
*/
AppenderPtr DOMConfigurator::findAppenderByName(log4cxx::helpers::Pool& p,
        log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
        apr_xml_elem* element,
        apr_xml_doc* doc,
        const LogString& appenderName,
        AppenderMap& appenders)
{
    AppenderPtr appender;
    std::string tagName(element->name);

    if (tagName == APPENDER_TAG)
    {
        if (appenderName == getAttribute(utf8Decoder, element, NAME_ATTR))
        {
            appender = parseAppender(p, utf8Decoder, element, doc, appenders);
        }
    }

    if (element->first_child && !appender)
    {
        appender = findAppenderByName(p, utf8Decoder, element->first_child, doc, appenderName, appenders);
    }

    if (element->next && !appender)
    {
        appender = findAppenderByName(p, utf8Decoder, element->next, doc, appenderName, appenders);
    }

    return appender;
}

/**
 Used internally to parse appenders by IDREF element.
*/
AppenderPtr DOMConfigurator::findAppenderByReference(
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* appenderRef,
    apr_xml_doc* doc,
    AppenderMap& appenders)
{
    LogString appenderName(subst(getAttribute(utf8Decoder, appenderRef, REF_ATTR)));
    AppenderMap::const_iterator match = appenders.find(appenderName);
    AppenderPtr appender;

    if (match != appenders.end())
    {
        appender = match->second;
    }
    else if (doc)
    {
        appender = findAppenderByName(p, utf8Decoder, doc->root, doc, appenderName, appenders);

        if (appender)
        {
            appenders.insert(AppenderMap::value_type(appenderName, appender));
        }
    }

    if (!appender)
    {
        LogLog::error(LOG4CXX_STR("No appender named [") +
                      appenderName + LOG4CXX_STR("] could be found."));
    }

    return appender;
}

/**
Used internally to parse an appender element.
*/
AppenderPtr DOMConfigurator::parseAppender(Pool& p,
        log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
        apr_xml_elem* appenderElement,
        apr_xml_doc* doc,
        AppenderMap& appenders)
{

    LogString className(subst(getAttribute(utf8Decoder, appenderElement, CLASS_ATTR)));
    LogLog::debug(LOG4CXX_STR("Class name: [") + className + LOG4CXX_STR("]"));

    try
    {
        ObjectPtr instance = Loader::loadClass(className).newInstance();
        AppenderPtr appender = instance;
        PropertySetter propSetter(appender);

        appender->setName(subst(getAttribute(utf8Decoder, appenderElement, NAME_ATTR)));

        for (apr_xml_elem* currentElement = appenderElement->first_child;
                currentElement;
                currentElement = currentElement->next)
        {

            std::string tagName(currentElement->name);

            // Parse appender parameters
            if (tagName == PARAM_TAG)
            {
                setParameter(p, utf8Decoder, currentElement, propSetter);
            }
            // Set appender layout
            else if (tagName == LAYOUT_TAG)
            {
                appender->setLayout(parseLayout(p, utf8Decoder, currentElement));
            }
            // Add filters
            else if (tagName == FILTER_TAG)
            {
                std::vector<log4cxx::spi::FilterPtr> filters;
                parseFilters(p, utf8Decoder, currentElement, filters);

                for (std::vector<log4cxx::spi::FilterPtr>::iterator iter = filters.begin();
                        iter != filters.end();
                        iter++)
                {
                    appender->addFilter(*iter);
                }
            }
            else if (tagName == ERROR_HANDLER_TAG)
            {
                parseErrorHandler(p, utf8Decoder, currentElement, appender, doc, appenders);
            }
            else if (tagName == ROLLING_POLICY_TAG)
            {
                RollingPolicyPtr rollPolicy(parseRollingPolicy(p, utf8Decoder, currentElement));
                RollingFileAppenderPtr rfa(appender);

                if (rfa != NULL)
                {
                    rfa->setRollingPolicy(rollPolicy);
                }
            }
            else if (tagName == TRIGGERING_POLICY_TAG)
            {
                ObjectPtr policy(parseTriggeringPolicy(p, utf8Decoder, currentElement));
                RollingFileAppenderPtr rfa(appender);

                if (rfa != NULL)
                {
                    rfa->setTriggeringPolicy(policy);
                }
                else
                {
                    log4cxx::net::SMTPAppenderPtr smtpa(appender);

                    if (smtpa != NULL)
                    {
                        log4cxx::spi::TriggeringEventEvaluatorPtr evaluator(policy);
                        smtpa->setEvaluator(evaluator);
                    }
                }
            }
            else if (tagName == APPENDER_REF_TAG)
            {
                LogString refName = subst(getAttribute(utf8Decoder, currentElement, REF_ATTR));

                if (appender->instanceof(AppenderAttachable::getStaticClass()))
                {
                    AppenderAttachablePtr aa(appender);
                    LogLog::debug(LOG4CXX_STR("Attaching appender named [") +
                                  refName + LOG4CXX_STR("] to appender named [") +
                                  appender->getName() + LOG4CXX_STR("]."));
                    aa->addAppender(findAppenderByReference(p, utf8Decoder, currentElement, doc, appenders));
                }
                else
                {
                    LogLog::error(LOG4CXX_STR("Requesting attachment of appender named [") +
                                  refName + LOG4CXX_STR("] to appender named [") + appender->getName() +
                                  LOG4CXX_STR("] which does not implement AppenderAttachable."));
                }
            }
        }

        propSetter.activate(p);
        return appender;
    }
    /* Yes, it's ugly.  But all of these exceptions point to the same
        problem: we can't create an Appender */
    catch (Exception& oops)
    {
        LogLog::error(LOG4CXX_STR("Could not create an Appender. Reported error follows."),
                      oops);
        return 0;
    }
}

/**
Used internally to parse an {@link ErrorHandler} element.
*/
void DOMConfigurator::parseErrorHandler(Pool& p,
                                        log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
                                        apr_xml_elem* element,
                                        AppenderPtr& appender,
                                        apr_xml_doc* doc,
                                        AppenderMap& appenders)
{

    ErrorHandlerPtr eh = OptionConverter::instantiateByClassName(
                             subst(getAttribute(utf8Decoder, element, CLASS_ATTR)),
                             ErrorHandler::getStaticClass(),
                             0);

    if (eh != 0)
    {
        eh->setAppender(appender);

        PropertySetter propSetter(eh);

        for (apr_xml_elem* currentElement = element->first_child;
                currentElement;
                currentElement = currentElement->next)
        {
            std::string tagName(currentElement->name);

            if (tagName == PARAM_TAG)
            {
                setParameter(p, utf8Decoder, currentElement, propSetter);
            }
            else if (tagName == APPENDER_REF_TAG)
            {
                eh->setBackupAppender(findAppenderByReference(p, utf8Decoder, currentElement, doc, appenders));
            }
            else if (tagName == LOGGER_REF)
            {
                LogString loggerName(getAttribute(utf8Decoder, currentElement, REF_ATTR));
                LoggerPtr logger = repository->getLogger(loggerName, loggerFactory);
                eh->setLogger(logger);
            }
            else if (tagName == ROOT_REF)
            {
                LoggerPtr root = repository->getRootLogger();
                eh->setLogger(root);
            }
        }

        propSetter.activate(p);
        ObjectPtrT<AppenderSkeleton> appSkeleton(appender);

        if (appSkeleton != 0)
        {
            appSkeleton->setErrorHandler(eh);
        }
    }
}

/**
 Used internally to parse a filter element.
*/
void DOMConfigurator::parseFilters(Pool& p,
                                   log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
                                   apr_xml_elem* element,
                                   std::vector<log4cxx::spi::FilterPtr>& filters)
{
    LogString clazz = subst(getAttribute(utf8Decoder, element, CLASS_ATTR));
    FilterPtr filter = OptionConverter::instantiateByClassName(clazz,
                       Filter::getStaticClass(), 0);

    if (filter != 0)
    {
        PropertySetter propSetter(filter);

        for (apr_xml_elem* currentElement = element->first_child;
                currentElement;
                currentElement = currentElement->next)
        {
            std::string tagName(currentElement->name);

            if (tagName == PARAM_TAG)
            {
                setParameter(p, utf8Decoder, currentElement, propSetter);
            }
        }

        propSetter.activate(p);
        filters.push_back(filter);
    }
}

/**
Used internally to parse an category or logger element.
*/
void DOMConfigurator::parseLogger(
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* loggerElement,
    apr_xml_doc* doc,
    AppenderMap& appenders)
{
    // Create a new Logger object from the <category> element.
    LogString loggerName = subst(getAttribute(utf8Decoder, loggerElement, NAME_ATTR));

    LogLog::debug(LOG4CXX_STR("Retreiving an instance of Logger."));
    LoggerPtr logger = repository->getLogger(loggerName, loggerFactory);

    // Setting up a logger needs to be an atomic operation, in order
    // to protect potential log operations while logger
    // configuration is in progress.
    LOCK_W sync(logger->getMutex());
    bool additivity = OptionConverter::toBoolean(
                          subst(getAttribute(utf8Decoder, loggerElement, ADDITIVITY_ATTR)),
                          true);

    LogLog::debug(LOG4CXX_STR("Setting [") + logger->getName() + LOG4CXX_STR("] additivity to [") +
                  (additivity ? LogString(LOG4CXX_STR("true")) : LogString(LOG4CXX_STR("false"))) + LOG4CXX_STR("]."));
    logger->setAdditivity(additivity);
    parseChildrenOfLoggerElement(p, utf8Decoder, loggerElement, logger, false, doc, appenders);
}

/**
 Used internally to parse the logger factory element.
*/
void DOMConfigurator::parseLoggerFactory(
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* factoryElement)
{
    LogString className(subst(getAttribute(utf8Decoder, factoryElement, CLASS_ATTR)));

    if (className.empty())
    {
        LogLog::error(LOG4CXX_STR("Logger Factory tag class attribute not found."));
        LogLog::debug(LOG4CXX_STR("No Logger Factory configured."));
    }
    else
    {
        LogLog::debug(LOG4CXX_STR("Desired logger factory: [") + className + LOG4CXX_STR("]"));
        loggerFactory = OptionConverter::instantiateByClassName(
                            className,
                            LoggerFactory::getStaticClass(),
                            0);
        PropertySetter propSetter(loggerFactory);

        for (apr_xml_elem* currentElement = factoryElement->first_child;
                currentElement;
                currentElement = currentElement->next)
        {
            std::string tagName(currentElement->name);

            if (tagName == PARAM_TAG)
            {
                setParameter(p, utf8Decoder, currentElement, propSetter);
            }
        }
    }
}

/**
 Used internally to parse the root logger element.
*/
void DOMConfigurator::parseRoot(
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* rootElement,
    apr_xml_doc* doc,
    AppenderMap& appenders)
{
    LoggerPtr root = repository->getRootLogger();
    // logger configuration needs to be atomic
    LOCK_W sync(root->getMutex());
    parseChildrenOfLoggerElement(p, utf8Decoder, rootElement, root, true, doc, appenders);
}

/**
 Used internally to parse the children of a logger element.
*/
void DOMConfigurator::parseChildrenOfLoggerElement(
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* loggerElement, LoggerPtr logger, bool isRoot,
    apr_xml_doc* doc,
    AppenderMap& appenders)
{

    PropertySetter propSetter(logger);

    // Remove all existing appenders from logger. They will be
    // reconstructed if need be.
    logger->removeAllAppenders();


    for (apr_xml_elem* currentElement = loggerElement->first_child;
            currentElement;
            currentElement = currentElement->next)
    {
        std::string tagName(currentElement->name);

        if (tagName == APPENDER_REF_TAG)
        {
            AppenderPtr appender = findAppenderByReference(p, utf8Decoder, currentElement, doc, appenders);
            LogString refName =  subst(getAttribute(utf8Decoder, currentElement, REF_ATTR));

            if (appender != 0)
            {
                LogLog::debug(LOG4CXX_STR("Adding appender named [") + refName +
                              LOG4CXX_STR("] to logger [") + logger->getName() + LOG4CXX_STR("]."));
            }
            else
            {
                LogLog::debug(LOG4CXX_STR("Appender named [") + refName +
                              LOG4CXX_STR("] not found."));
            }

            logger->addAppender(appender);

        }
        else if (tagName == LEVEL_TAG)
        {
            parseLevel(p, utf8Decoder, currentElement, logger, isRoot);
        }
        else if (tagName == PRIORITY_TAG)
        {
            parseLevel(p, utf8Decoder, currentElement, logger, isRoot);
        }
        else if (tagName == PARAM_TAG)
        {
            setParameter(p, utf8Decoder, currentElement, propSetter);
        }
    }

    propSetter.activate(p);
}

/**
 Used internally to parse a layout element.
*/
LayoutPtr DOMConfigurator::parseLayout (
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* layout_element)
{
    LogString className(subst(getAttribute(utf8Decoder, layout_element, CLASS_ATTR)));
    LogLog::debug(LOG4CXX_STR("Parsing layout of class: \"") + className + LOG4CXX_STR("\""));

    try
    {
        ObjectPtr instance = Loader::loadClass(className).newInstance();
        LayoutPtr layout = instance;
        PropertySetter propSetter(layout);

        for (apr_xml_elem* currentElement = layout_element->first_child;
                currentElement;
                currentElement = currentElement->next)
        {
            std::string tagName(currentElement->name);

            if (tagName == PARAM_TAG)
            {
                setParameter(p, utf8Decoder, currentElement, propSetter);
            }
        }

        propSetter.activate(p);
        return layout;
    }
    catch (Exception& oops)
    {
        LogLog::error(LOG4CXX_STR("Could not create the Layout. Reported error follows."),
                      oops);
        return 0;
    }
}

/**
 Used internally to parse a triggering policy
*/
ObjectPtr DOMConfigurator::parseTriggeringPolicy (
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* layout_element)
{
    LogString className = subst(getAttribute(utf8Decoder, layout_element, CLASS_ATTR));
    LogLog::debug(LOG4CXX_STR("Parsing triggering policy of class: \"") + className + LOG4CXX_STR("\""));

    try
    {
        ObjectPtr instance = Loader::loadClass(className).newInstance();
        PropertySetter propSetter(instance);

        for (apr_xml_elem* currentElement = layout_element->first_child;
                currentElement;
                currentElement = currentElement->next)
        {
            std::string tagName(currentElement->name);

            if (tagName == PARAM_TAG)
            {
                setParameter(p, utf8Decoder, currentElement, propSetter);
            }
            else if (tagName == FILTER_TAG)
            {
                std::vector<log4cxx::spi::FilterPtr> filters;
                parseFilters(p, utf8Decoder, currentElement, filters);
                FilterBasedTriggeringPolicyPtr fbtp(instance);

                if (fbtp != NULL)
                {
                    for (std::vector<log4cxx::spi::FilterPtr>::iterator iter = filters.begin();
                            iter != filters.end();
                            iter++)
                    {
                        fbtp->addFilter(*iter);
                    }
                }
            }
        }

        propSetter.activate(p);
        return instance;
    }
    catch (Exception& oops)
    {
        LogLog::error(LOG4CXX_STR("Could not create the TriggeringPolicy. Reported error follows."),
                      oops);
        return 0;
    }
}

/**
 Used internally to parse a triggering policy
*/
RollingPolicyPtr DOMConfigurator::parseRollingPolicy (
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* layout_element)
{
    LogString className = subst(getAttribute(utf8Decoder, layout_element, CLASS_ATTR));
    LogLog::debug(LOG4CXX_STR("Parsing rolling policy of class: \"") + className + LOG4CXX_STR("\""));

    try
    {
        ObjectPtr instance = Loader::loadClass(className).newInstance();
        RollingPolicyPtr layout = instance;
        PropertySetter propSetter(layout);

        for (apr_xml_elem* currentElement = layout_element->first_child;
                currentElement;
                currentElement = currentElement->next)
        {
            std::string tagName(currentElement->name);

            if (tagName == PARAM_TAG)
            {
                setParameter(p, utf8Decoder, currentElement, propSetter);
            }
        }

        propSetter.activate(p);
        return layout;
    }
    catch (Exception& oops)
    {
        LogLog::error(LOG4CXX_STR("Could not create the RollingPolicy. Reported error follows."),
                      oops);
        return 0;
    }
}



/**
 Used internally to parse a level  element.
*/
void DOMConfigurator::parseLevel(
    log4cxx::helpers::Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* element, LoggerPtr logger, bool isRoot)
{
    LogString loggerName = logger->getName();

    if (isRoot)
    {
        loggerName = LOG4CXX_STR("root");
    }

    LogString levelStr(subst(getAttribute(utf8Decoder, element, VALUE_ATTR)));
    LogLog::debug(LOG4CXX_STR("Level value for ") + loggerName + LOG4CXX_STR(" is [") + levelStr + LOG4CXX_STR("]."));

    if (StringHelper::equalsIgnoreCase(levelStr, LOG4CXX_STR("INHERITED"), LOG4CXX_STR("inherited"))
            || StringHelper::equalsIgnoreCase(levelStr, LOG4CXX_STR("NULL"), LOG4CXX_STR("null")))
    {
        if (isRoot)
        {
            LogLog::error(LOG4CXX_STR("Root level cannot be inherited. Ignoring directive."));
        }
        else
        {
            logger->setLevel(0);
        }
    }
    else
    {
        LogString className(subst(getAttribute(utf8Decoder, element, CLASS_ATTR)));

        if (className.empty())
        {
            logger->setLevel(OptionConverter::toLevel(levelStr, Level::getDebug()));
        }
        else
        {
            LogLog::debug(LOG4CXX_STR("Desired Level sub-class: [") + className + LOG4CXX_STR("]"));

            try
            {
                Level::LevelClass& levelClass =
                    (Level::LevelClass&)Loader::loadClass(className);
                LevelPtr level = levelClass.toLevel(levelStr);
                logger->setLevel(level);
            }
            catch (Exception& oops)
            {
                LogLog::error(
                    LOG4CXX_STR("Could not create level [") + levelStr +
                    LOG4CXX_STR("]. Reported error follows."),
                    oops);

                return;
            }
            catch (...)
            {
                LogLog::error(
                    LOG4CXX_STR("Could not create level [") + levelStr);

                return;
            }
        }
    }

    LogLog::debug(loggerName + LOG4CXX_STR(" level set to ") +
                  logger->getEffectiveLevel()->toString());
}

void DOMConfigurator::setParameter(log4cxx::helpers::Pool& p,
                                   log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
                                   apr_xml_elem* elem,
                                   PropertySetter& propSetter)
{
    LogString name(subst(getAttribute(utf8Decoder, elem, NAME_ATTR)));
    LogString value(subst(getAttribute(utf8Decoder, elem, VALUE_ATTR)));
    value = subst(value);
    propSetter.setProperty(name, value, p);
}

void DOMConfigurator::doConfigure(const File& filename, spi::LoggerRepositoryPtr& repository1)
{
    repository1->setConfigured(true);
    this->repository = repository1;
    LogString msg(LOG4CXX_STR("DOMConfigurator configuring file "));
    msg.append(filename.getPath());
    msg.append(LOG4CXX_STR("..."));
    LogLog::debug(msg);

    loggerFactory = new DefaultLoggerFactory();

    Pool p;
    apr_file_t* fd;

    log4cxx_status_t rv = filename.open(&fd, APR_READ, APR_OS_DEFAULT, p);

    if (rv != APR_SUCCESS)
    {
        LogString msg2(LOG4CXX_STR("Could not open file ["));
        msg2.append(filename.getPath());
        msg2.append(LOG4CXX_STR("]."));
        LogLog::error(msg2);
    }
    else
    {
        apr_xml_parser* parser = NULL;
        apr_xml_doc* doc = NULL;
        rv = apr_xml_parse_file(p.getAPRPool(), &parser, &doc, fd, 2000);

        if (rv != APR_SUCCESS)
        {
            char errbuf[2000];
            char errbufXML[2000];
            LogString msg2(LOG4CXX_STR("Error parsing file ["));
            msg2.append(filename.getPath());
            msg2.append(LOG4CXX_STR("], "));
            apr_strerror(rv, errbuf, sizeof(errbuf));
            LOG4CXX_DECODE_CHAR(lerrbuf, std::string(errbuf));
            msg2.append(lerrbuf);

            if (parser)
            {
                apr_xml_parser_geterror(parser, errbufXML, sizeof(errbufXML));
                LOG4CXX_DECODE_CHAR(lerrbufXML, std::string(errbufXML));
                msg2.append(lerrbufXML);
            }

            LogLog::error(msg2);
        }
        else
        {
            AppenderMap appenders;
            CharsetDecoderPtr utf8Decoder(CharsetDecoder::getUTF8Decoder());
            parse(p, utf8Decoder, doc->root, doc, appenders);
        }
    }
}

void DOMConfigurator::configure(const std::string& filename)
{
    File file(filename);
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
}

#if LOG4CXX_WCHAR_T_API
void DOMConfigurator::configure(const std::wstring& filename)
{
    File file(filename);
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
}
#endif

#if LOG4CXX_UNICHAR_API
void DOMConfigurator::configure(const std::basic_string<UniChar>& filename)
{
    File file(filename);
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
}
#endif

#if LOG4CXX_CFSTRING_API
void DOMConfigurator::configure(const CFStringRef& filename)
{
    File file(filename);
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
}
#endif


void DOMConfigurator::configureAndWatch(const std::string& filename)
{
    configureAndWatch(filename, FileWatchdog::DEFAULT_DELAY);
}

#if LOG4CXX_WCHAR_T_API
void DOMConfigurator::configureAndWatch(const std::wstring& filename)
{
    configureAndWatch(filename, FileWatchdog::DEFAULT_DELAY);
}
#endif

#if LOG4CXX_UNICHAR_API
void DOMConfigurator::configureAndWatch(const std::basic_string<UniChar>& filename)
{
    configureAndWatch(filename, FileWatchdog::DEFAULT_DELAY);
}
#endif

#if LOG4CXX_CFSTRING_API
void DOMConfigurator::configureAndWatch(const CFStringRef& filename)
{
    configureAndWatch(filename, FileWatchdog::DEFAULT_DELAY);
}
#endif

void DOMConfigurator::configureAndWatch(const std::string& filename, long delay)
{
    File file(filename);
#if APR_HAS_THREADS

    if ( xdog )
    {
        APRInitializer::unregisterCleanup(xdog);
        delete xdog;
    }

    xdog = new XMLWatchdog(file);
    APRInitializer::registerCleanup(xdog);
    xdog->setDelay(delay);
    xdog->start();
#else
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
#endif
}

#if LOG4CXX_WCHAR_T_API
void DOMConfigurator::configureAndWatch(const std::wstring& filename, long delay)
{
    File file(filename);
#if APR_HAS_THREADS

    if ( xdog )
    {
        APRInitializer::unregisterCleanup(xdog);
        delete xdog;
    }

    xdog = new XMLWatchdog(file);
    APRInitializer::registerCleanup(xdog);
    xdog->setDelay(delay);
    xdog->start();
#else
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
#endif
}
#endif

#if LOG4CXX_UNICHAR_API
void DOMConfigurator::configureAndWatch(const std::basic_string<UniChar>& filename, long delay)
{
    File file(filename);
#if APR_HAS_THREADS

    if ( xdog )
    {
        APRInitializer::unregisterCleanup(xdog);
        delete xdog;
    }

    xdog = new XMLWatchdog(file);
    APRInitializer::registerCleanup(xdog);
    xdog->setDelay(delay);
    xdog->start();
#else
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
#endif
}
#endif

#if LOG4CXX_CFSTRING_API
void DOMConfigurator::configureAndWatch(const CFStringRef& filename, long delay)
{
    File file(filename);
#if APR_HAS_THREADS

    if ( xdog )
    {
        APRInitializer::unregisterCleanup(xdog);
        delete xdog;
    }

    xdog = new XMLWatchdog(file);
    APRInitializer::registerCleanup(xdog);
    xdog->setDelay(delay);
    xdog->start();
#else
    DOMConfigurator().doConfigure(file, LogManager::getLoggerRepository());
#endif
}
#endif

void DOMConfigurator::parse(
    Pool& p,
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* element,
    apr_xml_doc* doc,
    AppenderMap& appenders)
{
    std::string rootElementName(element->name);

    if (rootElementName != CONFIGURATION_TAG)
    {
        if (rootElementName == OLD_CONFIGURATION_TAG)
        {
            //LogLog::warn(LOG4CXX_STR("The <")+String(OLD_CONFIGURATION_TAG)+
            // LOG4CXX_STR("> element has been deprecated."));
            //LogLog::warn(LOG4CXX_STR("Use the <")+String(CONFIGURATION_TAG)+
            // LOG4CXX_STR("> element instead."));
        }
        else
        {
            LogLog::error(LOG4CXX_STR("DOM element is - not a <configuration> element."));
            return;
        }
    }

    LogString debugAttrib = subst(getAttribute(utf8Decoder, element, INTERNAL_DEBUG_ATTR));

    static const LogString NuLL(LOG4CXX_STR("NULL"));
    LogLog::debug(LOG4CXX_STR("debug attribute= \"") + debugAttrib + LOG4CXX_STR("\"."));

    // if the log4j.dtd is not specified in the XML file, then the
    // "debug" attribute is returned as the empty string.
    if (!debugAttrib.empty() && debugAttrib != NuLL)
    {
        LogLog::setInternalDebugging(OptionConverter::toBoolean(debugAttrib, true));
    }
    else
    {
        LogLog::debug(LOG4CXX_STR("Ignoring internalDebug attribute."));
    }


    LogString confDebug = subst(getAttribute(utf8Decoder, element, CONFIG_DEBUG_ATTR));

    if (!confDebug.empty() && confDebug != NuLL)
    {
        LogLog::warn(LOG4CXX_STR("The \"configDebug\" attribute is deprecated."));
        LogLog::warn(LOG4CXX_STR("Use the \"internalDebug\" attribute instead."));
        LogLog::setInternalDebugging(OptionConverter::toBoolean(confDebug, true));
    }

    LogString thresholdStr = subst(getAttribute(utf8Decoder, element, THRESHOLD_ATTR));
    LogLog::debug(LOG4CXX_STR("Threshold =\"") + thresholdStr + LOG4CXX_STR("\"."));

    if (!thresholdStr.empty() && thresholdStr != NuLL)
    {
        repository->setThreshold(thresholdStr);
    }

    LogString strstrValue = subst(getAttribute(utf8Decoder, element, STRINGSTREAM_ATTR));
    LogLog::debug(LOG4CXX_STR("Stringstream =\"") + strstrValue + LOG4CXX_STR("\"."));

    if (!strstrValue.empty() && strstrValue != NuLL)
    {
        MessageBufferUseStaticStream();
    }

    apr_xml_elem* currentElement;

    for (currentElement = element->first_child;
            currentElement;
            currentElement = currentElement->next)
    {
        std::string tagName(currentElement->name);

        if (tagName == CATEGORY_FACTORY_TAG)
        {
            parseLoggerFactory(p, utf8Decoder, currentElement);
        }
    }

    for (currentElement = element->first_child;
            currentElement;
            currentElement = currentElement->next)
    {
        std::string tagName(currentElement->name);

        if (tagName == CATEGORY || tagName == LOGGER)
        {
            parseLogger(p, utf8Decoder, currentElement, doc, appenders);
        }
        else if (tagName == ROOT_TAG)
        {
            parseRoot(p, utf8Decoder, currentElement, doc, appenders);
        }
    }
}

LogString DOMConfigurator::subst(const LogString& value)
{
    try
    {
        return OptionConverter::substVars(value, props);
    }
    catch (IllegalArgumentException& e)
    {
        LogLog::warn(LOG4CXX_STR("Could not perform variable substitution."), e);
        return value;
    }
}


LogString DOMConfigurator::getAttribute(
    log4cxx::helpers::CharsetDecoderPtr& utf8Decoder,
    apr_xml_elem* element,
    const std::string& attrName)
{
    LogString attrValue;

    for (apr_xml_attr* attr = element->attr;
            attr;
            attr = attr->next)
    {
        if (attrName == attr->name)
        {
            ByteBuffer buf((char*) attr->value, strlen(attr->value));
            utf8Decoder->decode(buf, attrValue);
        }
    }

    return attrValue;
}
