LevelPtr OptionConverter::toLevel()

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;
}