You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rm...@apache.org on 2021/11/06 00:43:14 UTC

[logging-log4cxx] 09/20: Made filter hierarchy ABI stable

This is an automated email from the ASF dual-hosted git repository.

rmiddleton pushed a commit to branch LOGCXX-510
in repository https://gitbox.apache.org/repos/asf/logging-log4cxx.git

commit bf869837dd9a7a1e93d08e059fc09fda6943c1e5
Author: Robert Middleton <ro...@rm5248.com>
AuthorDate: Fri Nov 5 17:30:13 2021 -0400

    Made filter hierarchy ABI stable
---
 src/main/cpp/andfilter.cpp                         | 28 ++++++----
 src/main/cpp/filter.cpp                            | 14 +++--
 src/main/cpp/levelmatchfilter.cpp                  | 33 +++++++++---
 src/main/cpp/levelrangefilter.cpp                  | 60 ++++++++++++++++++---
 src/main/cpp/loggermatchfilter.cpp                 | 35 +++++++++---
 src/main/cpp/mapfilter.cpp                         | 63 +++++++++++++++++++---
 src/main/cpp/stringmatchfilter.cpp                 | 46 +++++++++++++---
 src/main/include/log4cxx/filter/andfilter.h        |  3 +-
 src/main/include/log4cxx/filter/levelmatchfilter.h | 14 ++---
 src/main/include/log4cxx/filter/levelrangefilter.h | 39 +++-----------
 .../include/log4cxx/filter/loggermatchfilter.h     | 14 ++---
 src/main/include/log4cxx/filter/mapfilter.h        | 48 +++++------------
 .../include/log4cxx/filter/stringmatchfilter.h     | 30 ++++-------
 .../log4cxx/private/filter_priv.h}                 | 31 ++++-------
 src/main/include/log4cxx/spi/filter.h              | 10 ++--
 15 files changed, 286 insertions(+), 182 deletions(-)

diff --git a/src/main/cpp/andfilter.cpp b/src/main/cpp/andfilter.cpp
index d5a24b0..d029e4f 100644
--- a/src/main/cpp/andfilter.cpp
+++ b/src/main/cpp/andfilter.cpp
@@ -19,24 +19,30 @@
 #include <log4cxx/spi/loggingevent.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/optionconverter.h>
+#include <log4cxx/private/filter_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::filter;
 using namespace log4cxx::spi;
 using namespace log4cxx::helpers;
 
-IMPLEMENT_LOG4CXX_OBJECT(AndFilter)
+#define priv static_cast<AndFilterPrivate*>(m_priv.get())
 
-struct AndFilter::priv_data{
-	priv_data() : headFilter(), tailFilter(), acceptOnMatch(true){}
+struct AndFilter::AndFilterPrivate : public FilterPrivate{
+	AndFilterPrivate() : FilterPrivate(),
+						headFilter(),
+						tailFilter(),
+						acceptOnMatch(true){}
 
 	log4cxx::spi::FilterPtr headFilter;
 	log4cxx::spi::FilterPtr tailFilter;
 	bool acceptOnMatch;
 };
 
+IMPLEMENT_LOG4CXX_OBJECT(AndFilter)
+
 AndFilter::AndFilter()
-	: m_priv( std::make_unique<priv_data>() )
+	: Filter( std::make_unique<AndFilterPrivate>() )
 {
 }
 
@@ -44,28 +50,28 @@ AndFilter::~AndFilter(){}
 
 void AndFilter::addFilter(const FilterPtr& filter)
 {
-	if (m_priv->headFilter == NULL)
+	if (priv->headFilter == NULL)
 	{
-		m_priv->headFilter = filter;
-		m_priv->tailFilter = filter;
+		priv->headFilter = filter;
+		priv->tailFilter = filter;
 	}
 	else
 	{
-		m_priv->tailFilter->setNext(filter);
+		priv->tailFilter->setNext(filter);
 	}
 }
 
 
 void AndFilter::setAcceptOnMatch(bool newValue)
 {
-	m_priv->acceptOnMatch = newValue;
+	priv->acceptOnMatch = newValue;
 }
 
 Filter::FilterDecision AndFilter::decide(
 	const spi::LoggingEventPtr& event) const
 {
 	bool accepted = true;
-	FilterPtr f(m_priv->headFilter);
+	FilterPtr f(priv->headFilter);
 
 	while (f != NULL)
 	{
@@ -75,7 +81,7 @@ Filter::FilterDecision AndFilter::decide(
 
 	if (accepted)
 	{
-		if (m_priv->acceptOnMatch)
+		if (priv->acceptOnMatch)
 		{
 			return Filter::ACCEPT;
 		}
diff --git a/src/main/cpp/filter.cpp b/src/main/cpp/filter.cpp
index d838286..3c47cca 100644
--- a/src/main/cpp/filter.cpp
+++ b/src/main/cpp/filter.cpp
@@ -17,23 +17,31 @@
 
 #include <log4cxx/logstring.h>
 #include <log4cxx/spi/filter.h>
+#include <log4cxx/private/filter_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::spi;
 using namespace log4cxx::helpers;
 
-Filter::Filter() : next()
+Filter::Filter() : m_priv(std::make_unique<FilterPrivate>())
 {
 }
 
+Filter::Filter(std::unique_ptr<FilterPrivate> priv) :
+	m_priv(std::move(priv)){
+
+}
+
+Filter::~Filter(){}
+
 FilterPtr Filter::getNext() const
 {
-	return next;
+	return m_priv->next;
 }
 
 void Filter::setNext(const FilterPtr& newNext)
 {
-	next = newNext;
+	m_priv->next = newNext;
 }
 
 void Filter::activateOptions(Pool&)
diff --git a/src/main/cpp/levelmatchfilter.cpp b/src/main/cpp/levelmatchfilter.cpp
index 4784269..22877f6 100644
--- a/src/main/cpp/levelmatchfilter.cpp
+++ b/src/main/cpp/levelmatchfilter.cpp
@@ -21,20 +21,30 @@
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/level.h>
+#include <log4cxx/private/filter_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::filter;
 using namespace log4cxx::spi;
 using namespace log4cxx::helpers;
 
-IMPLEMENT_LOG4CXX_OBJECT(LevelMatchFilter)
+#define priv static_cast<LevelMatchFilterPrivate*>(m_priv.get())
+
+struct LevelMatchFilter::LevelMatchFilterPrivate : public FilterPrivate {
+	bool acceptOnMatch;
+	LevelPtr levelToMatch;
+};
 
+IMPLEMENT_LOG4CXX_OBJECT(LevelMatchFilter)
 
 LevelMatchFilter::LevelMatchFilter()
-	: acceptOnMatch(true)
+	: Filter(std::make_unique<LevelMatchFilterPrivate>())
 {
+	priv->acceptOnMatch = true;
 }
 
+LevelMatchFilter::~LevelMatchFilter(){}
+
 void LevelMatchFilter::setOption(const LogString& option,
 	const LogString& value)
 {
@@ -48,26 +58,26 @@ void LevelMatchFilter::setOption(const LogString& option,
 	else if (StringHelper::equalsIgnoreCase(option,
 			LOG4CXX_STR("ACCEPTONMATCH"), LOG4CXX_STR("acceptonmatch")))
 	{
-		acceptOnMatch = OptionConverter::toBoolean(value, acceptOnMatch);
+		priv->acceptOnMatch = OptionConverter::toBoolean(value, priv->acceptOnMatch);
 	}
 }
 
 void LevelMatchFilter::setLevelToMatch(const LogString& levelToMatch1)
 {
-	this->levelToMatch = OptionConverter::toLevel(levelToMatch1, this->levelToMatch);
+	priv->levelToMatch = OptionConverter::toLevel(levelToMatch1, priv->levelToMatch);
 }
 
 LogString LevelMatchFilter::getLevelToMatch() const
 {
-	return levelToMatch->toString();
+	return priv->levelToMatch->toString();
 }
 
 Filter::FilterDecision LevelMatchFilter::decide(
 	const log4cxx::spi::LoggingEventPtr& event) const
 {
-	if (levelToMatch != 0 && levelToMatch->equals(event->getLevel()))
+	if (priv->levelToMatch != 0 && priv->levelToMatch->equals(event->getLevel()))
 	{
-		if (acceptOnMatch)
+		if (priv->acceptOnMatch)
 		{
 			return Filter::ACCEPT;
 		}
@@ -82,3 +92,12 @@ Filter::FilterDecision LevelMatchFilter::decide(
 	}
 }
 
+void LevelMatchFilter::setAcceptOnMatch(bool acceptOnMatch1)
+{
+	priv->acceptOnMatch = acceptOnMatch1;
+}
+
+bool LevelMatchFilter::getAcceptOnMatch() const
+{
+	return priv->acceptOnMatch;
+}
diff --git a/src/main/cpp/levelrangefilter.cpp b/src/main/cpp/levelrangefilter.cpp
index 7747b7d..8d79ae1 100644
--- a/src/main/cpp/levelrangefilter.cpp
+++ b/src/main/cpp/levelrangefilter.cpp
@@ -21,20 +21,37 @@
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/optionconverter.h>
 #include <log4cxx/level.h>
+#include <log4cxx/private/filter_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::filter;
 using namespace log4cxx::spi;
 using namespace log4cxx::helpers;
 
+#define priv static_cast<LevelRangeFilterPrivate*>(m_priv.get())
+
+struct LevelRangeFilter::LevelRangeFilterPrivate : public FilterPrivate{
+	LevelRangeFilterPrivate() : acceptOnMatch(false), levelMin(Level::getAll()), levelMax(Level::getOff()){}
+
+	/**
+	Do we return ACCEPT when a match occurs. Default is
+	<code>false</code>, so that later filters get run by default
+	*/
+	bool acceptOnMatch;
+	LevelPtr levelMin;
+	LevelPtr levelMax;
+};
+
 IMPLEMENT_LOG4CXX_OBJECT(LevelRangeFilter)
 
 
 LevelRangeFilter::LevelRangeFilter()
-	: acceptOnMatch(false), levelMin(Level::getAll()), levelMax(Level::getOff())
+	: Filter(std::make_unique<LevelRangeFilterPrivate>())
 {
 }
 
+LevelRangeFilter::~LevelRangeFilter(){}
+
 void LevelRangeFilter::setOption(const LogString& option,
 	const LogString& value)
 {
@@ -42,30 +59,30 @@ void LevelRangeFilter::setOption(const LogString& option,
 	if (StringHelper::equalsIgnoreCase(option,
 			LOG4CXX_STR("LEVELMIN"), LOG4CXX_STR("levelmin")))
 	{
-		levelMin = OptionConverter::toLevel(value, levelMin);
+		priv->levelMin = OptionConverter::toLevel(value, priv->levelMin);
 	}
 	else if (StringHelper::equalsIgnoreCase(option,
 			LOG4CXX_STR("LEVELMAX"), LOG4CXX_STR("levelmax")))
 	{
-		levelMax = OptionConverter::toLevel(value, levelMax);
+		priv->levelMax = OptionConverter::toLevel(value, priv->levelMax);
 	}
 	else if (StringHelper::equalsIgnoreCase(option,
 			LOG4CXX_STR("ACCEPTONMATCH"), LOG4CXX_STR("acceptonmatch")))
 	{
-		acceptOnMatch = OptionConverter::toBoolean(value, acceptOnMatch);
+		priv->acceptOnMatch = OptionConverter::toBoolean(value, priv->acceptOnMatch);
 	}
 }
 
 Filter::FilterDecision LevelRangeFilter::decide(
 	const spi::LoggingEventPtr& event) const
 {
-	if (levelMin != 0 && !event->getLevel()->isGreaterOrEqual(levelMin))
+	if (priv->levelMin != 0 && !event->getLevel()->isGreaterOrEqual(priv->levelMin))
 	{
 		// level of event is less than minimum
 		return Filter::DENY;
 	}
 
-	if (levelMax != 0 && event->getLevel()->toInt() > levelMax->toInt())
+	if (priv->levelMax != 0 && event->getLevel()->toInt() > priv->levelMax->toInt())
 	{
 		// level of event is greater than maximum
 		// Alas, there is no Level.isGreater method. and using
@@ -74,7 +91,7 @@ Filter::FilterDecision LevelRangeFilter::decide(
 		return Filter::DENY;
 	}
 
-	if (acceptOnMatch)
+	if (priv->acceptOnMatch)
 	{
 		// this filter set up to bypass later filters and always return
 		// accept if level in range
@@ -87,3 +104,32 @@ Filter::FilterDecision LevelRangeFilter::decide(
 	}
 }
 
+void LevelRangeFilter::setLevelMin(const LevelPtr& levelMin1)
+{
+	priv->levelMin = levelMin1;
+}
+
+const LevelPtr& LevelRangeFilter::getLevelMin() const
+{
+	return priv->levelMin;
+}
+
+void LevelRangeFilter::setLevelMax(const LevelPtr& levelMax1)
+{
+	priv->levelMax = levelMax1;
+}
+
+const LevelPtr& LevelRangeFilter::getLevelMax() const
+{
+	return priv->levelMax;
+}
+
+void LevelRangeFilter::setAcceptOnMatch(bool acceptOnMatch1)
+{
+	priv->acceptOnMatch = acceptOnMatch1;
+}
+
+bool LevelRangeFilter::getAcceptOnMatch() const
+{
+	return priv->acceptOnMatch;
+}
diff --git a/src/main/cpp/loggermatchfilter.cpp b/src/main/cpp/loggermatchfilter.cpp
index 17a659b..9a1e2c3 100644
--- a/src/main/cpp/loggermatchfilter.cpp
+++ b/src/main/cpp/loggermatchfilter.cpp
@@ -20,28 +20,42 @@
 #include <log4cxx/spi/loggingevent.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/optionconverter.h>
+#include <log4cxx/private/filter_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::filter;
 using namespace log4cxx::spi;
 using namespace log4cxx::helpers;
 
+#define priv static_cast<LoggerMatchFilterPrivate*>(m_priv.get())
+
+struct LoggerMatchFilter::LoggerMatchFilterPrivate : public FilterPrivate {
+	LoggerMatchFilterPrivate() : FilterPrivate(),
+		acceptOnMatch(true),
+		loggerToMatch(LOG4CXX_STR("root")){}
+
+	bool acceptOnMatch;
+	LogString loggerToMatch;
+};
+
 IMPLEMENT_LOG4CXX_OBJECT(LoggerMatchFilter)
 
 
 LoggerMatchFilter::LoggerMatchFilter()
-	: acceptOnMatch(true), loggerToMatch(LOG4CXX_STR("root"))
+	: Filter(std::make_unique<LoggerMatchFilterPrivate>())
 {
 }
 
+LoggerMatchFilter::~LoggerMatchFilter(){}
+
 void LoggerMatchFilter::setLoggerToMatch(const LogString& value)
 {
-	loggerToMatch = value;
+	priv->loggerToMatch = value;
 }
 
 LogString LoggerMatchFilter::getLoggerToMatch() const
 {
-	return loggerToMatch;
+	return priv->loggerToMatch;
 }
 
 void LoggerMatchFilter::setOption(const LogString& option,
@@ -56,18 +70,18 @@ void LoggerMatchFilter::setOption(const LogString& option,
 	else if (StringHelper::equalsIgnoreCase(option,
 			LOG4CXX_STR("ACCEPTONMATCH"), LOG4CXX_STR("acceptonmatch")))
 	{
-		acceptOnMatch = OptionConverter::toBoolean(value, acceptOnMatch);
+		priv->acceptOnMatch = OptionConverter::toBoolean(value, priv->acceptOnMatch);
 	}
 }
 
 Filter::FilterDecision LoggerMatchFilter::decide(
 	const spi::LoggingEventPtr& event) const
 {
-	bool matchOccured = loggerToMatch == event->getLoggerName();
+	bool matchOccured = priv->loggerToMatch == event->getLoggerName();
 
 	if (matchOccured)
 	{
-		if (acceptOnMatch)
+		if (priv->acceptOnMatch)
 		{
 			return Filter::ACCEPT;
 		}
@@ -82,3 +96,12 @@ Filter::FilterDecision LoggerMatchFilter::decide(
 	}
 }
 
+void LoggerMatchFilter::setAcceptOnMatch(bool acceptOnMatch1)
+{
+	priv->acceptOnMatch = acceptOnMatch1;
+}
+
+bool LoggerMatchFilter::getAcceptOnMatch() const
+{
+	return priv->acceptOnMatch;
+}
diff --git a/src/main/cpp/mapfilter.cpp b/src/main/cpp/mapfilter.cpp
index 5ea3110..ebde150 100644
--- a/src/main/cpp/mapfilter.cpp
+++ b/src/main/cpp/mapfilter.cpp
@@ -20,47 +20,61 @@
 #include <log4cxx/spi/loggingevent.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/optionconverter.h>
+#include <log4cxx/private/filter_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::filter;
 using namespace log4cxx::spi;
 using namespace log4cxx::helpers;
 
+#define priv static_cast<MapFilterPrivate*>(m_priv.get())
+
+struct MapFilter::MapFilterPrivate : public FilterPrivate {
+	MapFilterPrivate() : FilterPrivate(),
+		acceptOnMatch(true), mustMatchAll(false){}
+
+	bool    acceptOnMatch;
+	bool    mustMatchAll; // true = AND; false = OR
+	KeyVals keyVals;
+};
+
 IMPLEMENT_LOG4CXX_OBJECT(MapFilter)
 
-MapFilter::MapFilter() : acceptOnMatch(true), mustMatchAll(false)
+MapFilter::MapFilter() : Filter(std::make_unique<MapFilterPrivate>())
 {
 
 }
 
+MapFilter::~MapFilter(){}
+
 void MapFilter::setOption(  const LogString& option,
 	const LogString& value)
 {
 	if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("ACCEPTONMATCH"), LOG4CXX_STR("acceptonmatch")))
 	{
-		acceptOnMatch = OptionConverter::toBoolean(value, acceptOnMatch);
+		priv->acceptOnMatch = OptionConverter::toBoolean(value, priv->acceptOnMatch);
 	}
 	else if (StringHelper::equalsIgnoreCase(option, LOG4CXX_STR("OPERATOR"), LOG4CXX_STR("operator")))
 	{
-		mustMatchAll = StringHelper::equalsIgnoreCase(value, LOG4CXX_STR("AND"), LOG4CXX_STR("and")) ? true : false;
+		priv->mustMatchAll = StringHelper::equalsIgnoreCase(value, LOG4CXX_STR("AND"), LOG4CXX_STR("and")) ? true : false;
 	}
 	else if (!option.empty() && !value.empty())
 	{
-		keyVals[option] = value;
+		priv->keyVals[option] = value;
 	}
 }
 
 Filter::FilterDecision MapFilter::decide(
 	const log4cxx::spi::LoggingEventPtr& event) const
 {
-	if (keyVals.empty())
+	if (priv->keyVals.empty())
 	{
 		return Filter::NEUTRAL;
 	}
 
 	bool matched = true;
 
-	for (KeyVals::const_iterator it = keyVals.begin(); it != keyVals.end(); ++it)
+	for (KeyVals::const_iterator it = priv->keyVals.begin(); it != priv->keyVals.end(); ++it)
 	{
 		LogString curval;
 		event->getMDC(it->first, curval);
@@ -74,13 +88,13 @@ Filter::FilterDecision MapFilter::decide(
 			matched = true;
 		}
 
-		if (mustMatchAll != matched)
+		if (priv->mustMatchAll != matched)
 		{
 			break;
 		}
 	}
 
-	if (acceptOnMatch)
+	if (priv->acceptOnMatch)
 	{
 		return matched ? Filter::ACCEPT : Filter::NEUTRAL;
 	}
@@ -89,3 +103,36 @@ Filter::FilterDecision MapFilter::decide(
 		return matched ? Filter::DENY : Filter::NEUTRAL;
 	}
 }
+
+void MapFilter::setKeyValue(const LogString& strKey, const LogString& strValue)
+{
+	priv->keyVals[strKey] = strValue;
+}
+
+const LogString& MapFilter::getValue(const LogString& strKey) const
+{
+	static  const LogString                 empty;
+	const KeyVals::const_iterator   it(priv->keyVals.find(strKey));
+
+	return (it != priv->keyVals.end() ? it->second : empty);
+}
+
+void MapFilter::setAcceptOnMatch(bool acceptOnMatch1)
+{
+	priv->acceptOnMatch = acceptOnMatch1;
+}
+
+bool MapFilter::getAcceptOnMatch() const
+{
+	return priv->acceptOnMatch;
+}
+
+bool MapFilter::getMustMatchAll() const
+{
+	return priv->mustMatchAll;
+}
+
+void MapFilter::setMustMatchAll(bool mustMatchAll1)
+{
+	priv->mustMatchAll = mustMatchAll1;
+}
diff --git a/src/main/cpp/stringmatchfilter.cpp b/src/main/cpp/stringmatchfilter.cpp
index 978a708..eb6c113 100644
--- a/src/main/cpp/stringmatchfilter.cpp
+++ b/src/main/cpp/stringmatchfilter.cpp
@@ -20,20 +20,33 @@
 #include <log4cxx/spi/loggingevent.h>
 #include <log4cxx/helpers/stringhelper.h>
 #include <log4cxx/helpers/optionconverter.h>
+#include <log4cxx/private/filter_priv.h>
 
 using namespace log4cxx;
 using namespace log4cxx::filter;
 using namespace log4cxx::spi;
 using namespace log4cxx::helpers;
 
+#define priv static_cast<StringMatchFilterPrivate*>(m_priv.get())
+
+struct StringMatchFilter::StringMatchFilterPrivate : public FilterPrivate {
+	StringMatchFilterPrivate() : FilterPrivate(),
+			acceptOnMatch(true),
+			stringToMatch(){}
+
+	bool acceptOnMatch;
+	LogString stringToMatch;
+};
+
 IMPLEMENT_LOG4CXX_OBJECT(StringMatchFilter)
 
 StringMatchFilter::StringMatchFilter() :
-	acceptOnMatch(true),
-	stringToMatch()
+	Filter(std::make_unique<StringMatchFilterPrivate>())
 {
 }
 
+StringMatchFilter::~StringMatchFilter(){}
+
 void StringMatchFilter::setOption(const LogString& option,
 	const LogString& value)
 {
@@ -41,12 +54,12 @@ void StringMatchFilter::setOption(const LogString& option,
 	if (StringHelper::equalsIgnoreCase(option,
 			LOG4CXX_STR("STRINGTOMATCH"), LOG4CXX_STR("stringtomatch")))
 	{
-		stringToMatch = value;
+		priv->stringToMatch = value;
 	}
 	else if (StringHelper::equalsIgnoreCase(option,
 			LOG4CXX_STR("ACCEPTONMATCH"), LOG4CXX_STR("acceptonmatch")))
 	{
-		acceptOnMatch = OptionConverter::toBoolean(value, acceptOnMatch);
+		priv->acceptOnMatch = OptionConverter::toBoolean(value, priv->acceptOnMatch);
 	}
 }
 
@@ -55,20 +68,20 @@ Filter::FilterDecision StringMatchFilter::decide(
 {
 	const LogString& msg = event->getRenderedMessage();
 
-	if (msg.empty() || stringToMatch.empty())
+	if (msg.empty() || priv->stringToMatch.empty())
 	{
 		return Filter::NEUTRAL;
 	}
 
 
-	if ( msg.find(stringToMatch) == LogString::npos )
+	if ( msg.find(priv->stringToMatch) == LogString::npos )
 	{
 		return Filter::NEUTRAL;
 	}
 	else
 	{
 		// we've got a match
-		if (acceptOnMatch)
+		if (priv->acceptOnMatch)
 		{
 			return Filter::ACCEPT;
 		}
@@ -79,3 +92,22 @@ Filter::FilterDecision StringMatchFilter::decide(
 	}
 }
 
+void StringMatchFilter::setStringToMatch(const LogString& stringToMatch1)
+{
+	priv->stringToMatch.assign(stringToMatch1);
+}
+
+const LogString& StringMatchFilter::getStringToMatch() const
+{
+	return priv->stringToMatch;
+}
+
+void StringMatchFilter::setAcceptOnMatch(bool acceptOnMatch1)
+{
+	priv->acceptOnMatch = acceptOnMatch1;
+}
+
+bool StringMatchFilter::getAcceptOnMatch() const
+{
+	return priv->acceptOnMatch;
+}
diff --git a/src/main/include/log4cxx/filter/andfilter.h b/src/main/include/log4cxx/filter/andfilter.h
index 03c43a4..2e4033e 100644
--- a/src/main/include/log4cxx/filter/andfilter.h
+++ b/src/main/include/log4cxx/filter/andfilter.h
@@ -79,8 +79,7 @@ namespace filter
 class LOG4CXX_EXPORT AndFilter: public log4cxx::spi::Filter
 {
 	private:
-		struct priv_data;
-		std::unique_ptr<priv_data> m_priv;
+		struct AndFilterPrivate;
 
 		AndFilter(const AndFilter&);
 		AndFilter& operator=(const AndFilter&);
diff --git a/src/main/include/log4cxx/filter/levelmatchfilter.h b/src/main/include/log4cxx/filter/levelmatchfilter.h
index 11266be..56aa50f 100644
--- a/src/main/include/log4cxx/filter/levelmatchfilter.h
+++ b/src/main/include/log4cxx/filter/levelmatchfilter.h
@@ -49,8 +49,7 @@ then {@link spi::Filter#DENY DENY} is returned. If there is no match,
 class LOG4CXX_EXPORT LevelMatchFilter : public spi::Filter
 {
 	private:
-		bool acceptOnMatch;
-		LevelPtr levelToMatch;
+		struct LevelMatchFilterPrivate;
 
 	public:
 		typedef spi::Filter BASE_CLASS;
@@ -61,6 +60,7 @@ class LOG4CXX_EXPORT LevelMatchFilter : public spi::Filter
 		END_LOG4CXX_CAST_MAP()
 
 		LevelMatchFilter();
+		~LevelMatchFilter();
 
 		/**
 		Set options
@@ -72,15 +72,9 @@ class LOG4CXX_EXPORT LevelMatchFilter : public spi::Filter
 
 		LogString getLevelToMatch() const;
 
-		inline void setAcceptOnMatch(bool acceptOnMatch1)
-		{
-			this->acceptOnMatch = acceptOnMatch1;
-		}
+		void setAcceptOnMatch(bool acceptOnMatch1);
 
-		inline bool getAcceptOnMatch() const
-		{
-			return acceptOnMatch;
-		}
+		bool getAcceptOnMatch() const;
 
 		/**
 		Return the decision of this filter.
diff --git a/src/main/include/log4cxx/filter/levelrangefilter.h b/src/main/include/log4cxx/filter/levelrangefilter.h
index 6b5afdd..9851e31 100644
--- a/src/main/include/log4cxx/filter/levelrangefilter.h
+++ b/src/main/include/log4cxx/filter/levelrangefilter.h
@@ -57,13 +57,7 @@ filter out events by level.
 class LOG4CXX_EXPORT LevelRangeFilter : public spi::Filter
 {
 	private:
-		/**
-		Do we return ACCEPT when a match occurs. Default is
-		<code>false</code>, so that later filters get run by default
-		*/
-		bool acceptOnMatch;
-		LevelPtr levelMin;
-		LevelPtr levelMax;
+		struct LevelRangeFilterPrivate;
 
 	public:
 		typedef spi::Filter BASE_CLASS;
@@ -74,6 +68,7 @@ class LOG4CXX_EXPORT LevelRangeFilter : public spi::Filter
 		END_LOG4CXX_CAST_MAP()
 
 		LevelRangeFilter();
+		~LevelRangeFilter();
 
 		/**
 		Set options
@@ -84,50 +79,32 @@ class LOG4CXX_EXPORT LevelRangeFilter : public spi::Filter
 		/**
 		Set the <code>LevelMin</code> option.
 		*/
-		void setLevelMin(const LevelPtr& levelMin1)
-		{
-			this->levelMin = levelMin1;
-		}
+		void setLevelMin(const LevelPtr& levelMin1);
 
 		/**
 		Get the value of the <code>LevelMin</code> option.
 		*/
-		const LevelPtr& getLevelMin() const
-		{
-			return levelMin;
-		}
+		const LevelPtr& getLevelMin() const;
 
 		/**
 		Set the <code>LevelMax</code> option.
 		*/
-		void setLevelMax(const LevelPtr& levelMax1)
-		{
-			this->levelMax = levelMax1;
-		}
+		void setLevelMax(const LevelPtr& levelMax1);
 
 		/**
 		Get the value of the <code>LevelMax</code> option.
 		*/
-		const LevelPtr& getLevelMax() const
-		{
-			return levelMax;
-		}
+		const LevelPtr& getLevelMax() const;
 
 		/**
 		Set the <code>AcceptOnMatch</code> option.
 		*/
-		inline void setAcceptOnMatch(bool acceptOnMatch1)
-		{
-			this->acceptOnMatch = acceptOnMatch1;
-		}
+		void setAcceptOnMatch(bool acceptOnMatch1);
 
 		/**
 		Get the value of the <code>AcceptOnMatch</code> option.
 		*/
-		inline bool getAcceptOnMatch() const
-		{
-			return acceptOnMatch;
-		}
+		bool getAcceptOnMatch() const;
 
 		/**
 		Return the decision of this filter.
diff --git a/src/main/include/log4cxx/filter/loggermatchfilter.h b/src/main/include/log4cxx/filter/loggermatchfilter.h
index 1d0063e..494213c 100644
--- a/src/main/include/log4cxx/filter/loggermatchfilter.h
+++ b/src/main/include/log4cxx/filter/loggermatchfilter.h
@@ -51,8 +51,7 @@ namespace filter
 class LOG4CXX_EXPORT LoggerMatchFilter : public spi::Filter
 {
 	private:
-		bool acceptOnMatch;
-		LogString loggerToMatch;
+		struct LoggerMatchFilterPrivate;
 
 	public:
 		typedef spi::Filter BASE_CLASS;
@@ -63,6 +62,7 @@ class LOG4CXX_EXPORT LoggerMatchFilter : public spi::Filter
 		END_LOG4CXX_CAST_MAP()
 
 		LoggerMatchFilter();
+		~LoggerMatchFilter();
 
 		/**
 		Set options
@@ -74,15 +74,9 @@ class LOG4CXX_EXPORT LoggerMatchFilter : public spi::Filter
 
 		LogString getLoggerToMatch() const;
 
-		inline void setAcceptOnMatch(bool acceptOnMatch1)
-		{
-			this->acceptOnMatch = acceptOnMatch1;
-		}
+		void setAcceptOnMatch(bool acceptOnMatch1);
 
-		inline bool getAcceptOnMatch() const
-		{
-			return acceptOnMatch;
-		}
+		bool getAcceptOnMatch() const;
 
 		/**
 		Return the decision of this filter.
diff --git a/src/main/include/log4cxx/filter/mapfilter.h b/src/main/include/log4cxx/filter/mapfilter.h
index 77305aa..67c49c5 100644
--- a/src/main/include/log4cxx/filter/mapfilter.h
+++ b/src/main/include/log4cxx/filter/mapfilter.h
@@ -45,9 +45,7 @@ class LOG4CXX_EXPORT MapFilter: public log4cxx::spi::Filter
 		typedef std::map < LogString, LogString > KeyVals;
 
 	private:
-		bool    acceptOnMatch;
-		bool    mustMatchAll; // true = AND; false = OR
-		KeyVals keyVals;
+		struct MapFilterPrivate;
 
 	public:
 		DECLARE_LOG4CXX_OBJECT(MapFilter)
@@ -57,6 +55,7 @@ class LOG4CXX_EXPORT MapFilter: public log4cxx::spi::Filter
 		END_LOG4CXX_CAST_MAP()
 
 		MapFilter();
+		~MapFilter();
 
 		/**
 		Set options
@@ -64,38 +63,17 @@ class LOG4CXX_EXPORT MapFilter: public log4cxx::spi::Filter
 		virtual void setOption(const LogString& option,
 			const LogString& value);
 
-		inline void setKeyValue(const LogString& strKey, const LogString& strValue)
-		{
-			this->keyVals[strKey] = strValue;
-		}
-
-		inline const LogString& getValue(const LogString& strKey) const
-		{
-			static  const LogString                 empty;
-			const KeyVals::const_iterator   it(this->keyVals.find(strKey));
-
-			return (it != keyVals.end() ? it->second : empty);
-		}
-
-		inline void setAcceptOnMatch(bool acceptOnMatch1)
-		{
-			this->acceptOnMatch = acceptOnMatch1;
-		}
-
-		inline bool getAcceptOnMatch() const
-		{
-			return acceptOnMatch;
-		}
-
-		inline bool getMustMatchAll() const
-		{
-			return mustMatchAll;
-		}
-
-		inline void setMustMatchAll(bool mustMatchAll1)
-		{
-			this->mustMatchAll = mustMatchAll1;
-		}
+		void setKeyValue(const LogString& strKey, const LogString& strValue);
+
+		const LogString& getValue(const LogString& strKey) const;
+
+		void setAcceptOnMatch(bool acceptOnMatch1);
+
+		bool getAcceptOnMatch() const;
+
+		bool getMustMatchAll() const;
+
+		void setMustMatchAll(bool mustMatchAll1);
 
 		/**
 		Returns {@link log4cxx::spi::Filter#NEUTRAL NEUTRAL}
diff --git a/src/main/include/log4cxx/filter/stringmatchfilter.h b/src/main/include/log4cxx/filter/stringmatchfilter.h
index 8e57ce3..1091ea1 100644
--- a/src/main/include/log4cxx/filter/stringmatchfilter.h
+++ b/src/main/include/log4cxx/filter/stringmatchfilter.h
@@ -53,8 +53,7 @@ seeting up a <code>StringMatchFilter</code>.
 class LOG4CXX_EXPORT StringMatchFilter : public spi::Filter
 {
 	private:
-		bool acceptOnMatch;
-		LogString stringToMatch;
+		struct StringMatchFilterPrivate;
 
 	public:
 		typedef spi::Filter BASE_CLASS;
@@ -65,6 +64,7 @@ class LOG4CXX_EXPORT StringMatchFilter : public spi::Filter
 		END_LOG4CXX_CAST_MAP()
 
 		StringMatchFilter();
+		~StringMatchFilter();
 
 		/**
 		Set options
@@ -72,25 +72,13 @@ class LOG4CXX_EXPORT StringMatchFilter : public spi::Filter
 		virtual void setOption(const LogString& option,
 			const LogString& value);
 
-		inline void setStringToMatch(const LogString& stringToMatch1)
-		{
-			this->stringToMatch.assign(stringToMatch1);
-		}
-
-		inline const LogString& getStringToMatch() const
-		{
-			return stringToMatch;
-		}
-
-		inline void setAcceptOnMatch(bool acceptOnMatch1)
-		{
-			this->acceptOnMatch = acceptOnMatch1;
-		}
-
-		inline bool getAcceptOnMatch() const
-		{
-			return acceptOnMatch;
-		}
+		void setStringToMatch(const LogString& stringToMatch1);
+
+		const LogString& getStringToMatch() const;
+
+		void setAcceptOnMatch(bool acceptOnMatch1);
+
+		bool getAcceptOnMatch() const;
 
 		/**
 		Returns {@link log4cxx::spi::Filter#NEUTRAL NEUTRAL}
diff --git a/src/main/cpp/filter.cpp b/src/main/include/log4cxx/private/filter_priv.h
similarity index 69%
copy from src/main/cpp/filter.cpp
copy to src/main/include/log4cxx/private/filter_priv.h
index d838286..68d8dca 100644
--- a/src/main/cpp/filter.cpp
+++ b/src/main/include/log4cxx/private/filter_priv.h
@@ -14,33 +14,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef LOG4CXX_FILTER_PRIVATE_H
+#define LOG4CXX_FILTER_PRIVATE_H
 
-#include <log4cxx/logstring.h>
 #include <log4cxx/spi/filter.h>
 
-using namespace log4cxx;
-using namespace log4cxx::spi;
-using namespace log4cxx::helpers;
-
-Filter::Filter() : next()
+namespace log4cxx
 {
-}
-
-FilterPtr Filter::getNext() const
+namespace spi
 {
-	return next;
-}
 
-void Filter::setNext(const FilterPtr& newNext)
-{
-	next = newNext;
-}
+struct Filter::FilterPrivate{
+    /**
+    Points to the next filter in the filter chain.
+    */
+    FilterPtr next;
+};
 
-void Filter::activateOptions(Pool&)
-{
 }
-
-void Filter::setOption(const LogString&, const LogString&)
-{
 }
 
+#endif
diff --git a/src/main/include/log4cxx/spi/filter.h b/src/main/include/log4cxx/spi/filter.h
index 1bdf876..1f07f36 100644
--- a/src/main/include/log4cxx/spi/filter.h
+++ b/src/main/include/log4cxx/spi/filter.h
@@ -68,12 +68,14 @@ xml::DOMConfigurator DOMConfigurator}.
 class LOG4CXX_EXPORT Filter : public virtual OptionHandler,
 	public virtual helpers::Object
 {
-		/**
-		Points to the next filter in the filter chain.
-		*/
-		FilterPtr next;
+protected:
+		struct FilterPrivate;
+		std::unique_ptr<FilterPrivate> m_priv;
+
 	public:
 		Filter();
+		Filter(std::unique_ptr<FilterPrivate> priv);
+		virtual ~Filter();
 
 		DECLARE_ABSTRACT_LOG4CXX_OBJECT(Filter)
 		BEGIN_LOG4CXX_CAST_MAP()