/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _LOG4CXX_SPI_FILTER_H
#define _LOG4CXX_SPI_FILTER_H

#include <log4cxx/helpers/objectptr.h>
#include <log4cxx/helpers/objectimpl.h>
#include <log4cxx/spi/optionhandler.h>
#include <log4cxx/spi/loggingevent.h>

namespace log4cxx
{
namespace spi
{
class Filter;
LOG4CXX_PTR_DEF(Filter);


/**
Users should extend this class to implement customized logging
event filtering. Note that Logger and
AppenderSkeleton, the parent class of all standard
appenders, have built-in filtering rules. It is suggested that you
first use and understand the built-in rules before rushing to write
your own custom filters.

<p>This abstract class assumes and also imposes that filters be
organized in a linear chain. The {@link #decide
decide(LoggingEvent)} method of each filter is called sequentially,
in the order of their addition to the chain.

<p>The {@link #decide decide(LoggingEvent)} method must return one
of the integer constants #DENY, #NEUTRAL or
#ACCEPT.

<p>If the value #DENY is returned, then the log event is
dropped immediately without consulting with the remaining
filters.

<p>If the value #NEUTRAL is returned, then the next filter
in the chain is consulted. If there are no more filters in the
chain, then the log event is logged. Thus, in the presence of no
filters, the default behaviour is to log all logging events.

<p>If the value #ACCEPT is returned, then the log
event is logged without consulting the remaining filters.

<p>The philosophy of log4cxx filters is largely inspired from the
Linux ipchains.

<p>Note that filtering is only supported by the {@link
xml::DOMConfigurator DOMConfigurator}.
*/
class LOG4CXX_EXPORT Filter : public virtual OptionHandler,
	public virtual helpers::ObjectImpl
{
		/**
		Points to the next filter in the filter chain.
		*/
		FilterPtr next;
	public:
		Filter();

		void addRef() const;
		void releaseRef() const;

		DECLARE_ABSTRACT_LOG4CXX_OBJECT(Filter)
		BEGIN_LOG4CXX_CAST_MAP()
		LOG4CXX_CAST_ENTRY(Filter)
		LOG4CXX_CAST_ENTRY(spi::OptionHandler)
		END_LOG4CXX_CAST_MAP()

		log4cxx::spi::FilterPtr getNext() const;
		void setNext(const log4cxx::spi::FilterPtr& newNext);

		enum FilterDecision
		{
			/**
			The log event must be dropped immediately without consulting
			            with the remaining filters, if any, in the chain.  */
			DENY = -1,
			/**
			This filter is neutral with respect to the log event. The
			remaining filters, if any, should be consulted for a final decision.
			*/
			NEUTRAL = 0,
			/**
			The log event must be logged immediately without consulting with
			the remaining filters, if any, in the chain.
			            */
			ACCEPT = 1

		};


		/**
		Usually filters options become active when set. We provide a

		default do-nothing implementation for convenience.
		*/
		void activateOptions(log4cxx::helpers::Pool& p);
		void setOption(const LogString& option, const LogString& value);

		/**
		<p>If the decision is <code>DENY</code>, then the event will be
		dropped. If the decision is <code>NEUTRAL</code>, then the next
		filter, if any, will be invoked. If the decision is ACCEPT then
		the event will be logged without consulting with other filters in
		the chain.

		@param event The LoggingEvent to decide upon.
		@return The decision of the filter.  */
		virtual FilterDecision decide(const LoggingEventPtr& event) const = 0;
};
}
}

#endif //_LOG4CXX_SPI_FILTER_H
