in src/main/cpp/optionconverter.cpp [303:380]
LevelPtr OptionConverter::toLevel(const LogString& value,
const LevelPtr& defaultValue)
{
size_t hashIndex = value.find(LOG4CXX_STR("#"));
if (hashIndex == LogString::npos)
{
if (value.empty())
{
return defaultValue;
}
else
{
if (LogLog::isDebugEnabled())
{
LogLog::debug(
((LogString) LOG4CXX_STR("OptionConverter::toLevel: no class name specified, level=["))
+ value
+ LOG4CXX_STR("]"));
}
// no class name specified : use standard Level class
return Level::toLevelLS(value, defaultValue);
}
}
LogString clazz = value.substr(hashIndex + 1);
LogString levelName = value.substr(0, hashIndex);
if (LogLog::isDebugEnabled())
{
LogLog::debug(LOG4CXX_STR("OptionConverter::toLevel: class=[")
+ clazz + LOG4CXX_STR("], level=[")
+ levelName + LOG4CXX_STR("]")
);
}
// This is degenerate case but you never know.
if (levelName.empty())
{
return Level::toLevelLS(value, defaultValue);
}
try
{
// Note: the dynamic_cast could fail across DLL boundaries.
// However, without the dynamic_cast a poorly formed XML file
// could attempt to load an invalid class as a filter, causing
// a crash. If it can't be converted, a std::bad_cast should be
// thrown(and caught by the exception handler below)
const Level::LevelClass& levelClass =
dynamic_cast<const Level::LevelClass&>(Loader::loadClass(clazz));
return levelClass.toLevel(levelName);
}
catch (ClassNotFoundException&)
{
LogLog::warn(((LogString) LOG4CXX_STR("custom level class ["))
+ clazz + LOG4CXX_STR("] not found."));
}
catch (Exception& oops)
{
LogLog::warn(
LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
LOG4CXX_STR("] conversion) failed."), oops);
}
catch(const std::bad_cast&)
{
LogLog::warn(
LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("] unable to be converted to "
"Level::LevelClass"));
}
catch (...)
{
LogLog::warn(
LOG4CXX_STR("class [") + clazz + LOG4CXX_STR("], level [") + levelName +
LOG4CXX_STR("] conversion) failed."));
}
return defaultValue;
}