in src/main/cpp/domconfigurator.cpp [210:337]
AppenderPtr DOMConfigurator::parseAppender(Pool& p,
LOG4CXX_NS::helpers::CharsetDecoderPtr& utf8Decoder,
apr_xml_elem* appenderElement,
apr_xml_doc* doc,
AppenderMap& appenders)
{
LogString className(subst(getAttribute(utf8Decoder, appenderElement, CLASS_ATTR)));
if (LogLog::isDebugEnabled())
{
LogLog::debug(LOG4CXX_STR("Class name: [") + className + LOG4CXX_STR("]"));
}
try
{
ObjectPtr instance = ObjectPtr(Loader::loadClass(className).newInstance());
AppenderPtr appender = LOG4CXX_NS::cast<Appender>(instance);
if(!appender){
LogLog::error(LOG4CXX_STR("Could not cast class of type [") + className + LOG4CXX_STR("] to appender"));
return AppenderPtr();
}
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_NS::spi::FilterPtr> filters;
parseFilters(p, utf8Decoder, currentElement, filters);
for (auto& item : filters)
{
appender->addFilter(item);
}
}
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 = LOG4CXX_NS::cast<RollingFileAppender>(appender);
if (rfa != NULL)
{
rfa->setRollingPolicy(rollPolicy);
}
}
else if (tagName == TRIGGERING_POLICY_TAG)
{
ObjectPtr policy(parseTriggeringPolicy(p, utf8Decoder, currentElement));
RollingFileAppenderPtr rfa = LOG4CXX_NS::cast<RollingFileAppender>(appender);
TriggeringPolicyPtr policyPtr = LOG4CXX_NS::cast<TriggeringPolicy>(policy);
if (rfa != NULL)
{
rfa->setTriggeringPolicy(policyPtr);
}
else
{
auto smtpa = LOG4CXX_NS::cast<LOG4CXX_NS::net::SMTPAppender>(appender);
if (smtpa != NULL)
{
auto evaluator = LOG4CXX_NS::cast<TriggeringEventEvaluator>(policy);
smtpa->setEvaluator(evaluator);
}
}
}
else if (tagName == APPENDER_REF_TAG)
{
LogString refName = subst(getAttribute(utf8Decoder, currentElement, REF_ATTR));
if (!refName.empty() && appender->instanceof(AppenderAttachable::getStaticClass()))
{
AppenderAttachablePtr aa = LOG4CXX_NS::cast<AppenderAttachable>(appender);
if (LogLog::isDebugEnabled())
{
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 if (refName.empty())
{
LogLog::error(LOG4CXX_STR("Can't add appender with empty ref attribute"));
}
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;
}
}