/*
 * 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_PATTERN_LAYOUT_H
#define _LOG4CXX_PATTERN_LAYOUT_H

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

#include <log4cxx/layout.h>
#include <log4cxx/pattern/loggingeventpatternconverter.h>
#include <log4cxx/pattern/formattinginfo.h>
#include <log4cxx/pattern/patternparser.h>

namespace log4cxx
{
LOG4CXX_LIST_DEF(LoggingEventPatternConverterList, log4cxx::pattern::LoggingEventPatternConverterPtr);
LOG4CXX_LIST_DEF(FormattingInfoList, log4cxx::pattern::FormattingInfoPtr);

/**
 * A flexible layout configurable with pattern string.
 *
 * <p>
 *  The goal of this class is to #format a {@link spi::LoggingEvent LoggingEvent} and
 *  return the results as a string. The results depend on the <em>conversion pattern</em>.
 * </p>
 *
 * <p>
 *  The conversion pattern is closely related to the conversion pattern of the printf
 *  function in C. A conversion pattern is composed of literal text and format control
 *  expressions called <em>conversion specifiers</em>.
 * </p>
 *
 * <p>
 *  <i>You are free to insert any literal text within the conversion pattern.</i>
 * </p>
 *
 * <p>
 *  Each conversion specifier starts with a percent sign (%) and is followed by optional
 *  <em>format modifiers</em> and a <em>conversion character</em>. The conversion character
 *  specifies the type of data, e.g. logger, level, date, thread name. The format modifiers
 *  control such things as field width, padding, left and right justification. The
 *  following is a simple example.
 * </p>
 *
 * <p>
 *  Let the conversion pattern be <strong>"%-5p [%t]: %m%n"</strong> and assume that the log4cxx
 *  environment was set to use a PatternLayout. Then the statements
 *  <pre>
 *      LoggerPtr root = Logger::getRoot();
 *      root->debug("Message 1");
 *      root->warn("Message 2");</pre>
 *  would yield the output
 *  <pre>
 *      DEBUG [main]: Message 1
 *      WARN  [main]: Message 2</pre>
 * </p>
 *
 * <p>
 *  Note that there is no explicit separator between text and conversion specifiers. The
 *  pattern parser knows when it has reached the end of a conversion specifier when it
 *  reads a conversion character. In the example above the conversion specifier <strong>%-5p</strong>
 *  means the level of the logging event should be left justified to a width of five
 *  characters.
 * </p>
 *
 * <p>The recognized conversion characters are:</p>
 *
 * <table border="1" cellpadding="8">
 *  <tr>
 *      <th align="center"><strong>Conversion Character</strong></th>
 *      <th align="center"><strong>Effect</strong></th>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>c</strong></td>
 *      <td>
 *          Used to output the logger of the logging event. The logger conversion specifier
 *          can be optionally followed by <em>precision specifier</em>, that is a decimal
 *          constant in brackets.
 *          <p>
 *              If a precision specifier is given, then only the corresponding number of
 *              right most components of the logger name will be printed. By default the
 *              logger name is printed in full.
 *          </p>
 *          <p>
 *              For example, for the logger name "a.b.c" the pattern <strong>%c{2}</strong> will
 *              output "b.c".
 *          </p>
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center">
 *          <p><strong>C</strong></p>
 *          <p><strong>class</strong></p>
 *      </td>
 *      <td>
 *          Used to output the class of the issuer of the logging event if the compiler
 *          used supports a macro to retrieve the method of the currently compiled line and
 *          if the LOG4CXX_TRACE-like macros are used to issue a logging request. In this
 *          case the macro LOG4CXX_* is expanded at compile time to generate location info
 *          of the logging event and adds the method name, besides file and line, if
 *          available. In most cases the provided method contains the classname and can
 *          therefore be retrieved form the location info as needed.
 *          <p>
 *              Currently supported compilers are those from Microsoft, GNU-C and Borland.
 *          </p>
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>d</strong></td>
 *      <td>
 *          Used to output the date of the logging event. The date conversion specifier may
 *          be followed by a set of braces containing a date and time pattern string
 *          compatible with java.text.SimpleDateFormat, <em>ABSOLUTE</em>, <em>DATE</em> or
 *          <em>ISO8601</em>. For example, <strong>%d{HH:mm:ss,SSS}</strong>,
 *          <strong>%d{dd&nbsp;MMM&nbsp;yyyy&nbsp;HH:mm:ss,SSS}</strong> or <strong>%d{DATE}</strong>. If no
 *          date format specifier is given then ISO8601 format is assumed.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>F</strong></td>
 *      <td>
 *          Used to output the file name where the logging request was issued.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>l</strong></td>
 *      <td>
 *          Used to output location information of the caller which generated the logging
 *          event.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>L</strong></td>
 *      <td>
 *          Used to output the line number from where the logging request was issued.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>m</strong></td>
 *      <td>
 *          Used to output the application supplied message associated with the logging
 *          event.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center">
 *          <strong>M</strong>
 *          <p><strong>method</strong></p>
 *      </td>
 *      <td>
 *          Used to output the method of the issuer of the logging event if the compiler
 *          used supports a macro to retrieve the method of the currently compiled line
 *          and if the LOG4CXX_TRACE-like macros are used to issue a logging request. In
 *          this case the macro LOG4CXX_* is expanded at compile time to generate location
 *          info of the logging event and adds the method name, besides file and line, if
 *          available. In most cases the provided method contains the classname which is
 *          ignored in every attempt to retrieve the method from the location info.
 *          <p>
 *              Currently supported compilers are those from Microsoft, GNU-C and Borland.
 *          </p>
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>n</strong></td>
 *      <td>
 *          Outputs the platform dependent line separator character or characters.
 *          <p>
 *              This conversion character offers practically the same performance as using
 *              non-portable line separator strings such as "\n", or "\r\n". Thus, it is the
 *              preferred way of specifying a line separator.
 *          </p>
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>p</strong></td>
 *      <td>Used to output the level of the logging event.</td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>r</strong></td>
 *      <td>
 *          Used to output the number of milliseconds elapsed since the start of the
 *          application until the creation of the logging event.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>t</strong></td>
 *      <td>Used to output the name of the thread that generated the logging event.</td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>x</strong></td>
 *      <td>
 *          Used to output the NDC (nested diagnostic context) associated with the thread that
 *          generated the logging event.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>X</strong></td>
 *      <td>
 *          Used to output the MDC (mapped diagnostic context) associated with the thread that
 *          generated the logging event. The <strong>X</strong> conversion character <em>must</em> be
 *          followed by the key for the map placed between braces, as in <strong>%X{clientNumber}</strong>
 *          where <code>clientNumber</code> is the key. The value in the MDC corresponding to
 *          the key will be output.
 *          <p>See MDC class for more details.</p>
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center"><strong>%</strong></td>
 *      <td>The sequence %% outputs a single percent sign.</td>
 *  </tr>
 * </table>
 *
 * <p>
 *  By default the relevant information is output as is. However, with the aid of format
 *  modifiers it is possible to change the minimum field width, the maximum field width
 *  and justification.
 * </p>
 *
 * <p>
 *  The optional format modifier is placed between the percent sign and the conversion
 *  character.
 * </p>
 *
 * <p>
 *  The first optional format modifier is the <em>left justification flag</em> which is
 *  just the minus (-) character. Then comes the optional <em>minimum field width</em>
 *  modifier. This is a decimal constant that represents the minimum number of characters
 *  to output. If the data item requires fewer characters, it is padded on either the left
 *  or the right until the minimum width is reached. The default is to pad on the left
 *  (right justify) but you can specify right padding with the left justification flag. The
 *  padding character is space. If the data item is larger than the minimum field width,
 *  the field is expanded to accommodate the data. The value is never truncated.
 * </p>
 *
 * <p>
 *  This behavior can be changed using the <em>maximum field width</em> modifier which is
 *  designated by a period followed by a decimal constant. If the data item is longer than
 *  the maximum field, then the extra characters are removed from the <em>beginning</em> of
 *  the data item and not from the end. For example, it the maximum field width is eight
 *  and the data item is ten characters long, then the first two characters of the data
 *  item are dropped. This behavior deviates from the printf function in C where truncation
 *  is done from the end.
 * </p>
 *
 * <p>Below are various format modifier examples for the logger conversion specifier.</p>
 *
 * <table border="1" cellpadding="8">
 *  <tr>
 *      <th align="center"><strong>Format modifier</strong></th>
 *      <th align="center"><strong>left justify</strong></th>
 *      <th align="center"><strong>minimum width</strong></th>
 *      <th align="center"><strong>maximum width</strong></th>
 *      <th align="center"><strong>comment</strong></th>
 *  </tr>
 *  <tr>
 *      <td align="center">%20c</td>
 *      <td align="center">false</td>
 *      <td align="center">20</td>
 *      <td align="center">none</td>
 *      <td>Left pad with spaces if the logger name is less than 20 characters long.</td>
 *  </tr>
 *  <tr>
 *      <td align="center">%-20c</td>
 *      <td align="center">true</td>
 *      <td align="center">20</td>
 *      <td align="center">none</td>
 *      <td>Right pad with spaces if the logger name is less than 20 characters long.</td>
 *  </tr>
 *  <tr>
 *      <td align="center">%.30c</td>
 *      <td align="center">NA</td>
 *      <td align="center">none</td>
 *      <td align="center">30</td>
 *      <td>Truncate from the beginning if the logger name is longer than 30 characters.</td>
 *  </tr>
 *  <tr>
 *      <td align="center">%20.30c</td>
 *      <td align="center">false</td>
 *      <td align="center">20</td>
 *      <td align="center">30</td>
 *      <td>
 *          Left pad with spaces if the logger name is shorter than 20 characters. However, if
 *          logger name is longer than 30 characters, then truncate from the beginning.
 *      </td>
 *  </tr>
 *  <tr>
 *      <td align="center">%-20.30c</td>
 *      <td align="center">true</td>
 *      <td align="center">20</td>
 *      <td align="center">30</td>
 *      <td>
 *          Right pad with spaces if the logger name is shorter than 20 characters. However, if
 *          logger name is longer than 30 characters, then truncate from the beginning.
 *      </td>
 *  </tr>
 * </table>
 *
 * <p>Below are some examples of conversion patterns.</p>
 *
 * <p><strong>%r [%t] %-5p %c %x - %m\n</strong></p>
 * <p>This is essentially the TTCC layout.</p>
 *
 * <p><strong>%-6r [%15.15t] %-5p %30.30c %x - %m\n</strong></p>
 *
 * <p>
 *  Similar to the TTCC layout except that the relative time is right padded if less than 6
 *  digits, thread name is right padded if less than 15 characters and truncated if longer
 *  and the logger name is left padded if shorter than 30 characters and truncated if
 *  longer.
 * </p>
 *
 * <p>
 *  The above text is largely inspired from Peter A. Darnell and Philip E. Margolis' highly
 *  recommended book "C -- a Software Engineering Approach", ISBN 0-387-97389-3.
 * </p>
 */
class LOG4CXX_EXPORT PatternLayout : public Layout
{
		/**
		 * Conversion pattern.
		 */
		LogString conversionPattern;

		/**
		 * Pattern converters.
		 */
		LoggingEventPatternConverterList patternConverters;

		/**
		 * Field widths and alignment corresponding to pattern converters.
		 */
		FormattingInfoList patternFields;

	public:
		DECLARE_LOG4CXX_OBJECT(PatternLayout)
		BEGIN_LOG4CXX_CAST_MAP()
		LOG4CXX_CAST_ENTRY(PatternLayout)
		LOG4CXX_CAST_ENTRY_CHAIN(Layout)
		END_LOG4CXX_CAST_MAP()

		/**
		 * Does nothing
		 */
		PatternLayout();

		/**
		 * Constructs a PatternLayout using the supplied conversion pattern.
		 */
		PatternLayout(const LogString& pattern);

		/**
		 * Set the <strong>ConversionPattern</strong> option. This is the string which
		 * controls formatting and consists of a mix of literal content and
		 * conversion specifiers.
		 */
		void setConversionPattern(const LogString& conversionPattern);

		/**
		 * Returns the value of the <strong>ConversionPattern</strong> option.
		 */
		inline LogString getConversionPattern() const
		{
			return conversionPattern;
		}

		/**
		 * Call createPatternParser
		 */
		virtual void activateOptions(log4cxx::helpers::Pool& p);

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

		/**
		 * The PatternLayout does not handle the throwable contained within
		 * {@link spi::LoggingEvent LoggingEvents}. Thus, it returns
		 * <code>true</code>.
		 */
		virtual bool ignoresThrowable() const
		{
			return true;
		}

		/**
		 * Produces a formatted string as specified by the conversion pattern.
		 */
		virtual void format(    LogString& output,
			const spi::LoggingEventPtr& event,
			log4cxx::helpers::Pool& pool) const;

	protected:
		virtual log4cxx::pattern::PatternMap getFormatSpecifiers();
};

LOG4CXX_PTR_DEF(PatternLayout);
} // namespace log4cxx

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

#endif //_LOG4CXX_PATTERN_LAYOUT_H
