This framework is based on log4j (see {@link http://jakarta.apache.org/log4j log4j} for details).

*

Design, strategies and part of the methods documentation are developed by log4j team * (Ceki Gülcü as log4j project founder and * {@link http://jakarta.apache.org/log4j/docs/contributors.html contributors}).

* *

PHP port, extensions and modifications by VxR. All rights reserved.
* For more information, please see {@link http://www.vxr.it/log4php/}.

* *

This software is published under the terms of the LGPL License * a copy of which has been included with this distribution in the LICENSE file.

* * @package log4php * @subpackage helpers */ /** * @ignore */ if (!defined('LOG4PHP_DIR')) define('LOG4PHP_DIR', dirname(__FILE__) . '/..'); if (!defined('LOG4PHP_LINE_SEP')) { if (substr(php_uname(), 0, 7) == "Windows") { /** * @ignore */ define('LOG4PHP_LINE_SEP', "\r\n"); } else { /** * @ignore */ define('LOG4PHP_LINE_SEP', "\n"); } } /** */ require_once(LOG4PHP_DIR . '/helpers/LoggerFormattingInfo.php'); require_once(LOG4PHP_DIR . '/helpers/LoggerPatternConverter.php'); require_once(LOG4PHP_DIR . '/LoggerLog.php'); define('LOG4PHP_LOGGER_PATTERN_PARSER_ESCAPE_CHAR', '%'); define('LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE', 0); define('LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE', 1); define('LOG4PHP_LOGGER_PATTERN_PARSER_MINUS_STATE', 2); define('LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE', 3); define('LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE', 4); define('LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE', 5); define('LOG4PHP_LOGGER_PATTERN_PARSER_FULL_LOCATION_CONVERTER', 1000); define('LOG4PHP_LOGGER_PATTERN_PARSER_METHOD_LOCATION_CONVERTER', 1001); define('LOG4PHP_LOGGER_PATTERN_PARSER_CLASS_LOCATION_CONVERTER', 1002); define('LOG4PHP_LOGGER_PATTERN_PARSER_FILE_LOCATION_CONVERTER', 1003); define('LOG4PHP_LOGGER_PATTERN_PARSER_LINE_LOCATION_CONVERTER', 1004); define('LOG4PHP_LOGGER_PATTERN_PARSER_RELATIVE_TIME_CONVERTER', 2000); define('LOG4PHP_LOGGER_PATTERN_PARSER_THREAD_CONVERTER', 2001); define('LOG4PHP_LOGGER_PATTERN_PARSER_LEVEL_CONVERTER', 2002); define('LOG4PHP_LOGGER_PATTERN_PARSER_NDC_CONVERTER', 2003); define('LOG4PHP_LOGGER_PATTERN_PARSER_MESSAGE_CONVERTER', 2004); define('LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601', 'Y-m-d H:i:s,u'); define('LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ABSOLUTE', 'H:i:s'); define('LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_DATE', 'd M Y H:i:s,u'); /** * Most of the work of the {@link LoggerPatternLayout} class * is delegated to the {@link LoggerPatternParser} class. * *

It is this class that parses conversion patterns and creates * a chained list of {@link LoggerPatternConverter} converters.

* * @author VxR * @version $Revision: 1.1 $ * @package log4php * @subpackage helpers * * @since 0.3 */ class LoggerPatternParser { var $state; var $currentLiteral; var $patternLength; var $i; /** * @var LoggerPatternConverter */ var $head = null; /** * @var LoggerPatternConverter */ var $tail = null; /** * @var LoggerFormattingInfo */ var $formattingInfo; /** * @var string pattern to parse */ var $pattern; /** * Constructor * * @param string $pattern */ function LoggerPatternParser($pattern) { LoggerLog::debug("LoggerPatternParser::LoggerPatternParser() pattern='$pattern'"); $this->pattern = $pattern; $this->patternLength = strlen($pattern); $this->formattingInfo = new LoggerFormattingInfo(); $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE; } /** * @param LoggerPatternConverter $pc */ function addToList($pc) { // LoggerLog::debug("LoggerPatternParser::addToList()"); if($this->head == null) { $this->head = $pc; $this->tail =& $this->head; } else { $this->tail->next = $pc; $this->tail =& $this->tail->next; } } /** * @return string */ function extractOption() { if(($this->i < $this->patternLength) and ($this->pattern{$this->i} == '{')) { $end = strpos($this->pattern, '}' , $this->i); if ($end !== false) { $r = substr($this->pattern, ($this->i + 1), ($end - $this->i - 1)); $this->i= $end + 1; return $r; } } return null; } /** * The option is expected to be in decimal and positive. In case of * error, zero is returned. */ function extractPrecisionOption() { $opt = $this->extractOption(); $r = 0; if ($opt !== null) { if (is_numeric($opt)) { $r = (int)$opt; if($r <= 0) { LoggerLog::warn("Precision option ({$opt}) isn't a positive integer."); $r = 0; } } else { LoggerLog::warn("Category option \"{$opt}\" not a decimal integer."); } } return $r; } function parse() { LoggerLog::debug("LoggerPatternParser::parse()"); $c = ''; $this->i = 0; $this->currentLiteral = ''; while ($this->i < $this->patternLength) { $c = $this->pattern{$this->i++}; // LoggerLog::debug("LoggerPatternParser::parse() char is now '$c' and currentLiteral is '{$this->currentLiteral}'"); switch($this->state) { case LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE: // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE'"); // In literal state, the last char is always a literal. if($this->i == $this->patternLength) { $this->currentLiteral .= $c; continue; } if($c == LOG4PHP_LOGGER_PATTERN_PARSER_ESCAPE_CHAR) { // LoggerLog::debug("LoggerPatternParser::parse() char is an escape char"); // peek at the next char. switch($this->pattern{$this->i}) { case LOG4PHP_LOGGER_PATTERN_PARSER_ESCAPE_CHAR: // LoggerLog::debug("LoggerPatternParser::parse() next char is an escape char"); $this->currentLiteral .= $c; $this->i++; // move pointer break; case 'n': // LoggerLog::debug("LoggerPatternParser::parse() next char is 'n'"); $this->currentLiteral .= LOG4PHP_LINE_SEP; $this->i++; // move pointer break; default: if(strlen($this->currentLiteral) != 0) { $this->addToList(new LoggerLiteralPatternConverter($this->currentLiteral)); LoggerLog::debug("LoggerPatternParser::parse() Parsed LITERAL converter: \"{$this->currentLiteral}\"."); } $this->currentLiteral = $c; $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE; $this->formattingInfo->reset(); } } else { $this->currentLiteral .= $c; } break; case LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE: // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE'"); $this->currentLiteral .= $c; switch($c) { case '-': $this->formattingInfo->leftAlign = true; break; case '.': $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE; break; default: if(ord($c) >= ord('0') and ord($c) <= ord('9')) { $this->formattingInfo->min = ord($c) - ord('0'); $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE; } else { $this->finalizeConverter($c); } } // switch break; case LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE: // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE'"); $this->currentLiteral .= $c; if(ord($c) >= ord('0') and ord($c) <= ord('9')) { $this->formattingInfo->min = ($this->formattingInfo->min * 10) + (ord(c) - ord('0')); } elseif ($c == '.') { $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE; } else { $this->finalizeConverter($c); } break; case LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE: // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE'"); $this->currentLiteral .= $c; if(ord($c) >= ord('0') and ord($c) <= ord('9')) { $this->formattingInfo->max = ord($c) - ord('0'); $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE; } else { LoggerLog::warn("LoggerPatternParser::parse() Error occured in position {$this->i}. Was expecting digit, instead got char \"{$c}\"."); $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE; } break; case LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE: // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE'"); $this->currentLiteral .= $c; if(ord($c) >= ord('0') and ord($c) <= ord('9')) { $this->formattingInfo->max = ($this->formattingInfo->max * 10) + (ord($c) - ord('0')); } else { $this->finalizeConverter($c); $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE; } break; } // switch } // while if(strlen($this->currentLiteral) != 0) { $this->addToList(new LoggerLiteralPatternConverter($this->currentLiteral)); // LoggerLog::debug("LoggerPatternParser::parse() Parsed LITERAL converter: \"{$this->currentLiteral}\"."); } return $this->head; } function finalizeConverter($c) { LoggerLog::debug("LoggerPatternParser::finalizeConverter() with char '$c'"); $pc = null; switch($c) { case 'c': $pc = new LoggerCategoryPatternConverter($this->formattingInfo, $this->extractPrecisionOption()); LoggerLog::debug("LoggerPatternParser::finalizeConverter() CATEGORY converter."); // $this->formattingInfo->dump(); $this->currentLiteral = ''; break; case 'C': $pc = new LoggerClassNamePatternConverter($this->formattingInfo, $this->extractPrecisionOption()); LoggerLog::debug("LoggerPatternParser::finalizeConverter() CLASSNAME converter."); //$this->formattingInfo->dump(); $this->currentLiteral = ''; break; case 'd': $dateFormatStr = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601; // ISO8601_DATE_FORMAT; $dOpt = $this->extractOption(); if($dOpt !== null) $dateFormatStr = $dOpt; if ($dateFormatStr == 'ISO8601') { $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601; } elseif($dateFormatStr == 'ABSOLUTE') { $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ABSOLUTE; } elseif($dateFormatStr == 'DATE') { $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_DATE; } else { $df = $dateFormatStr; if ($df == null) { $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601; } } $pc = new LoggerDatePatternConverter($this->formattingInfo, $df); $this->currentLiteral = ''; break; case 'F': $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_FILE_LOCATION_CONVERTER); LoggerLog::debug("LoggerPatternParser::finalizeConverter() File name converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 'l': $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_FULL_LOCATION_CONVERTER); LoggerLog::debug("LoggerPatternParser::finalizeConverter() Location converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 'L': $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_LINE_LOCATION_CONVERTER); LoggerLog::debug("LoggerPatternParser::finalizeConverter() LINE NUMBER converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 'm': $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_MESSAGE_CONVERTER); LoggerLog::debug("LoggerPatternParser::finalizeConverter() MESSAGE converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 'M': $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_METHOD_LOCATION_CONVERTER); //LogLog.debug("METHOD converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 'p': $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_LEVEL_CONVERTER); //LogLog.debug("LEVEL converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 'r': $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_RELATIVE_TIME_CONVERTER); LoggerLog::debug("LoggerPatternParser::finalizeConverter() RELATIVE TIME converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 't': $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_THREAD_CONVERTER); LoggerLog::debug("LoggerPatternParser::finalizeConverter() THREAD converter."); //formattingInfo.dump(); $this->currentLiteral = ''; break; case 'u': if($this->i < $this->patternLength) { $cNext = $this->pattern{$this->i}; if(ord($cNext) >= ord('0') and ord($cNext) <= ord('9')) { $pc = new LoggerUserFieldPatternConverter($this->formattingInfo, (string)(ord($cNext) - ord('0'))); LoggerLog::debug("LoggerPatternParser::finalizeConverter() USER converter [{$cNext}]."); // formattingInfo.dump(); $this->currentLiteral = ''; $this->i++; } else { LoggerLog::warn("LoggerPatternParser::finalizeConverter() Unexpected char '{$cNext}' at position {$this->i}."); } } break; case 'x': $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_NDC_CONVERTER); LoggerLog::debug("LoggerPatternParser::finalizeConverter() NDC converter."); $this->currentLiteral = ''; break; case 'X': $xOpt = $this->extractOption(); $pc = new LoggerMDCPatternConverter($this->formattingInfo, $xOpt); LoggerLog::debug("LoggerPatternParser::finalizeConverter() MDC converter."); $this->currentLiteral = ''; break; default: LoggerLog::warn("LoggerPatternParser::finalizeConverter() Unexpected char [$c] at position {$this->i} in conversion pattern."); $pc = new LoggerLiteralPatternConverter($this->currentLiteral); $this->currentLiteral = ''; } $this->addConverter($pc); } function addConverter($pc) { $this->currentLiteral = ''; // Add the pattern converter to the list. $this->addToList($pc); // Next pattern is assumed to be a literal. $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE; // Reset formatting info $this->formattingInfo->reset(); } } ?>