AppenderPtr DOMConfigurator::parseAppender()

in src/main/cpp/domconfigurator.cpp [208:323]


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 = ObjectPtr(Loader::loadClass(className).newInstance());
		AppenderPtr appender = log4cxx::cast<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 = log4cxx::cast<RollingFileAppender>(appender);

				if (rfa != NULL)
				{
					rfa->setRollingPolicy(rollPolicy);
				}
			}
			else if (tagName == TRIGGERING_POLICY_TAG)
			{
				ObjectPtr policy(parseTriggeringPolicy(p, utf8Decoder, currentElement));
				RollingFileAppenderPtr rfa = log4cxx::cast<RollingFileAppender>(appender);
				TriggeringPolicyPtr policyPtr = log4cxx::cast<TriggeringPolicy>(policy);

				if (rfa != NULL)
				{
					rfa->setTriggeringPolicy(policyPtr);
				}
				else
				{
					auto smtpa = log4cxx::cast<log4cxx::net::SMTPAppender>(appender);

					if (smtpa != NULL)
					{
						auto evaluator = log4cxx::cast<TriggeringEventEvaluator>(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 = log4cxx::cast<AppenderAttachable>(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;
	}
}