/*
 * 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.
 */

#if !defined(_LOG4CXX_ROLLING_ROLLING_POLICY_BASE_H)
#define _LOG4CXX_ROLLING_ROLLING_POLICY_BASE_H

#if defined(_MSC_VER)
	#pragma warning ( push )
	#pragma warning ( disable: 4231 4251 4275 4786 )
#endif


#include <log4cxx/helpers/object.h>
#include <log4cxx/logger.h>
#include <log4cxx/logmanager.h>
#include <log4cxx/rolling/rollingpolicy.h>
#include <log4cxx/pattern/patternconverter.h>
#include <log4cxx/pattern/formattinginfo.h>
#include <log4cxx/pattern/patternparser.h>

namespace log4cxx
{
namespace rolling
{
LOG4CXX_LIST_DEF(PatternConverterList, log4cxx::pattern::PatternConverterPtr);
LOG4CXX_LIST_DEF(FormattingInfoList, log4cxx::pattern::FormattingInfoPtr);

/**
 * Implements methods common to most, it not all, rolling
 * policies.
 *
 *
 *
 */
class LOG4CXX_EXPORT RollingPolicyBase :
	public virtual RollingPolicy,
	public virtual helpers::ObjectImpl
{
	protected:
		DECLARE_ABSTRACT_LOG4CXX_OBJECT(RollingPolicyBase)
		BEGIN_LOG4CXX_CAST_MAP()
		LOG4CXX_CAST_ENTRY(RollingPolicy)
		LOG4CXX_CAST_ENTRY(spi::OptionHandler)
		END_LOG4CXX_CAST_MAP()


	private:
		/**
		 * File name pattern converters.
		 */
		PatternConverterList patternConverters;

		/**
		 * File name field specifiers.
		 */
		FormattingInfoList patternFields;

		/**
		 * File name pattern.
		 */
		LogString fileNamePatternStr;


	public:
		RollingPolicyBase();
		virtual ~RollingPolicyBase();
		void addRef() const;
		void releaseRef() const;
		virtual void activateOptions(log4cxx::helpers::Pool& p) = 0;
		virtual log4cxx::pattern::PatternMap getFormatSpecifiers() const = 0;

		virtual void setOption(const LogString& option,
			const LogString& value);

		/**
		 * Set file name pattern.
		 * @param fnp file name pattern.
		 */
		void setFileNamePattern(const LogString& fnp);

		/**
		 * Get file name pattern.
		 * @return file name pattern.
		 */
		LogString getFileNamePattern() const;


#ifdef LOG4CXX_MULTI_PROCESS
		PatternConverterList getPatternConverterList()
		{
			return patternConverters;
		}
#endif
	protected:
		/**
		 *   Parse file name pattern.
		 */
		void parseFileNamePattern();

		/**
		 * Format file name.
		 *
		 * @param obj object to be evaluted in formatting, may not be null.
		 * @param buf string buffer to which formatted file name is appended, may not be null.
		 * @param p memory pool.
		 */
		void formatFileName(log4cxx::helpers::ObjectPtr& obj,
			LogString& buf, log4cxx::helpers::Pool& p) const;

		log4cxx::pattern::PatternConverterPtr getIntegerPatternConverter() const;
		log4cxx::pattern::PatternConverterPtr getDatePatternConverter() const;


};
}
}


#if defined(_MSC_VER)
	#pragma warning ( pop )
#endif

#endif
