source: branches/comu-ver2/data/module/log4php/php4/log4php/helpers/LoggerPatternParser.php @ 18701

Revision 18701, 18.4 KB checked in by nanasess, 14 years ago (diff)

Copyright の更新(#601)

Line 
1<?php
2/**
3 * log4php is a PHP port of the log4j java logging package.
4 *
5 * <p>This framework is based on log4j (see {@link http://jakarta.apache.org/log4j log4j} for details).</p>
6 * <p>Design, strategies and part of the methods documentation are developed by log4j team
7 * (Ceki Gülcü as log4j project founder and
8 * {@link http://jakarta.apache.org/log4j/docs/contributors.html contributors}).</p>
9 *
10 * <p>PHP port, extensions and modifications by VxR. All rights reserved.<br>
11 * For more information, please see {@link http://www.vxr.it/log4php/}.</p>
12 *
13 * <p>This software is published under the terms of the LGPL License
14 * a copy of which has been included with this distribution in the LICENSE file.</p>
15 *
16 * @package log4php
17 * @subpackage helpers
18 */
19
20/**
21 * @ignore
22 */
23if (!defined('LOG4PHP_DIR')) define('LOG4PHP_DIR', dirname(__FILE__) . '/..');
24
25if (!defined('LOG4PHP_LINE_SEP')) {
26    if (substr(php_uname(), 0, 7) == "Windows") {
27        /**
28         * @ignore
29         */
30        define('LOG4PHP_LINE_SEP', "\r\n");
31    } else {
32        /**
33         * @ignore
34         */
35        define('LOG4PHP_LINE_SEP', "\n");
36    }
37}
38 
39/**
40 */
41require_once(LOG4PHP_DIR . '/helpers/LoggerPatternConverter.php');
42require_once(LOG4PHP_DIR . '/helpers/LoggerFormattingInfo.php');
43require_once(LOG4PHP_DIR . '/LoggerLog.php');
44
45define('LOG4PHP_LOGGER_PATTERN_PARSER_ESCAPE_CHAR',         '%');
46
47define('LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE',       0);
48define('LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE',     1);
49define('LOG4PHP_LOGGER_PATTERN_PARSER_MINUS_STATE',         2);
50define('LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE',           3);
51define('LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE',           4);
52define('LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE',           5);
53
54define('LOG4PHP_LOGGER_PATTERN_PARSER_FULL_LOCATION_CONVERTER',         1000);
55define('LOG4PHP_LOGGER_PATTERN_PARSER_METHOD_LOCATION_CONVERTER',       1001);
56define('LOG4PHP_LOGGER_PATTERN_PARSER_CLASS_LOCATION_CONVERTER',        1002);
57define('LOG4PHP_LOGGER_PATTERN_PARSER_FILE_LOCATION_CONVERTER',         1003);
58define('LOG4PHP_LOGGER_PATTERN_PARSER_LINE_LOCATION_CONVERTER',         1004);
59
60define('LOG4PHP_LOGGER_PATTERN_PARSER_RELATIVE_TIME_CONVERTER',         2000);
61define('LOG4PHP_LOGGER_PATTERN_PARSER_THREAD_CONVERTER',                2001);
62define('LOG4PHP_LOGGER_PATTERN_PARSER_LEVEL_CONVERTER',                 2002);
63define('LOG4PHP_LOGGER_PATTERN_PARSER_NDC_CONVERTER',                   2003);
64define('LOG4PHP_LOGGER_PATTERN_PARSER_MESSAGE_CONVERTER',               2004);
65
66define('LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601',    'Y-m-d H:i:s,u');
67define('LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ABSOLUTE',   'H:i:s');
68define('LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_DATE',       'd M Y H:i:s,u');
69
70/**
71 * Most of the work of the {@link LoggerPatternLayout} class
72 * is delegated to the {@link LoggerPatternParser} class.
73 *
74 * <p>It is this class that parses conversion patterns and creates
75 * a chained list of {@link LoggerPatternConverter} converters.</p>
76 *
77 * @author VxR <vxr@vxr.it>
78 * @version $Revision: 1.9 $
79 * @package log4php
80 * @subpackage helpers
81 *
82 * @since 0.3
83 */
84class LoggerPatternParser {
85
86    var $state;
87    var $currentLiteral;
88    var $patternLength;
89    var $i;
90   
91    /**
92     * @var LoggerPatternConverter
93     */
94    var $head = null;
95     
96    /**
97     * @var LoggerPatternConverter
98     */
99    var $tail = null;
100   
101    /**
102     * @var LoggerFormattingInfo
103     */
104    var $formattingInfo;
105   
106    /**
107     * @var string pattern to parse
108     */
109    var $pattern;
110
111    /**
112     * Constructor
113     *
114     * @param string $pattern
115     */
116    function LoggerPatternParser($pattern)
117    {
118        LoggerLog::debug("LoggerPatternParser::LoggerPatternParser() pattern='$pattern'");
119   
120        $this->pattern = $pattern;
121        $this->patternLength =  strlen($pattern);
122        $this->formattingInfo = new LoggerFormattingInfo();
123        $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE;
124    }
125
126    /**
127     * @param LoggerPatternConverter $pc
128     */
129    function addToList($pc)
130    {
131        // LoggerLog::debug("LoggerPatternParser::addToList()");
132   
133        if($this->head == null) {
134            $this->head = $pc;
135            $this->tail =& $this->head;
136        } else {
137            $this->tail->next = $pc;
138            $this->tail =& $this->tail->next;
139        }
140    }
141
142    /**
143     * @return string
144     */
145    function extractOption()
146    {
147        if(($this->i < $this->patternLength) and ($this->pattern{$this->i} == '{')) {
148            $end = strpos($this->pattern, '}' , $this->i);
149            if ($end !== false) {
150                $r = substr($this->pattern, ($this->i + 1), ($end - $this->i - 1));
151                $this->i= $end + 1;
152                return $r;
153            }
154        }
155        return null;
156    }
157
158    /**
159     * The option is expected to be in decimal and positive. In case of
160     * error, zero is returned. 
161     */
162    function extractPrecisionOption()
163    {
164        $opt = $this->extractOption();
165        $r = 0;
166        if ($opt !== null) {
167            if (is_numeric($opt)) {
168                $r = (int)$opt;
169                if($r <= 0) {
170                    LoggerLog::warn("Precision option ({$opt}) isn't a positive integer.");
171                    $r = 0;
172                }
173            } else {
174                LoggerLog::warn("Category option \"{$opt}\" not a decimal integer.");
175            }
176        }
177        return $r;
178    }
179
180    function parse()
181    {
182        LoggerLog::debug("LoggerPatternParser::parse()");
183   
184        $c = '';
185        $this->i = 0;
186        $this->currentLiteral = '';
187        while ($this->i < $this->patternLength) {
188            $c = $this->pattern{$this->i++};
189//            LoggerLog::debug("LoggerPatternParser::parse() char is now '$c' and currentLiteral is '{$this->currentLiteral}'");           
190            switch($this->state) {
191                case LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE:
192                    // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE'");
193                    // In literal state, the last char is always a literal.
194                    if($this->i == $this->patternLength) {
195                        $this->currentLiteral .= $c;
196                        continue;
197                    }
198                    if($c == LOG4PHP_LOGGER_PATTERN_PARSER_ESCAPE_CHAR) {
199                        // LoggerLog::debug("LoggerPatternParser::parse() char is an escape char");                   
200                        // peek at the next char.
201                        switch($this->pattern{$this->i}) {
202                            case LOG4PHP_LOGGER_PATTERN_PARSER_ESCAPE_CHAR:
203                                // LoggerLog::debug("LoggerPatternParser::parse() next char is an escape char");                   
204                                $this->currentLiteral .= $c;
205                                $this->i++; // move pointer
206                                break;
207                            case 'n':
208                                // LoggerLog::debug("LoggerPatternParser::parse() next char is 'n'");                           
209                                $this->currentLiteral .= LOG4PHP_LINE_SEP;
210                                $this->i++; // move pointer
211                                break;
212                            default:
213                                if(strlen($this->currentLiteral) != 0) {
214                                    $this->addToList(new LoggerLiteralPatternConverter($this->currentLiteral));
215                                    LoggerLog::debug("LoggerPatternParser::parse() Parsed LITERAL converter: \"{$this->currentLiteral}\".");
216                                }
217                                $this->currentLiteral = $c;
218                                $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE;
219                                $this->formattingInfo->reset();
220                        }
221                    } else {
222                        $this->currentLiteral .= $c;
223                    }
224                    break;
225              case LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE:
226                    // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_CONVERTER_STATE'");             
227                    $this->currentLiteral .= $c;
228                    switch($c) {
229                        case '-':
230                            $this->formattingInfo->leftAlign = true;
231                            break;
232                        case '.':
233                            $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE;
234                            break;
235                        default:
236                            if(ord($c) >= ord('0') and ord($c) <= ord('9')) {
237                                $this->formattingInfo->min = ord($c) - ord('0');
238                                $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE;
239                            } else {
240                                $this->finalizeConverter($c);
241                            }
242                    } // switch
243                    break;
244              case LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE:
245                    // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_MIN_STATE'");             
246                    $this->currentLiteral .= $c;
247                    if(ord($c) >= ord('0') and ord($c) <= ord('9')) {
248                        $this->formattingInfo->min = ($this->formattingInfo->min * 10) + (ord(c) - ord('0'));
249                    } elseif ($c == '.') {
250                        $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE;
251                    } else {
252                        $this->finalizeConverter($c);
253                    }
254                    break;
255              case LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE:
256                    // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_DOT_STATE'");             
257                    $this->currentLiteral .= $c;
258                    if(ord($c) >= ord('0') and ord($c) <= ord('9')) {
259                        $this->formattingInfo->max = ord($c) - ord('0');
260                        $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE;
261                    } else {
262                      LoggerLog::warn("LoggerPatternParser::parse() Error occured in position {$this->i}. Was expecting digit, instead got char \"{$c}\".");
263                      $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE;
264                    }
265                    break;
266              case LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE:
267                    // LoggerLog::debug("LoggerPatternParser::parse() state is 'LOG4PHP_LOGGER_PATTERN_PARSER_MAX_STATE'");             
268                    $this->currentLiteral .= $c;
269                    if(ord($c) >= ord('0') and ord($c) <= ord('9')) {
270                        $this->formattingInfo->max = ($this->formattingInfo->max * 10) + (ord($c) - ord('0'));
271                    } else {
272                      $this->finalizeConverter($c);
273                      $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE;
274                    }
275                    break;
276            } // switch
277        } // while
278        if(strlen($this->currentLiteral) != 0) {
279            $this->addToList(new LoggerLiteralPatternConverter($this->currentLiteral));
280            // LoggerLog::debug("LoggerPatternParser::parse() Parsed LITERAL converter: \"{$this->currentLiteral}\".");
281        }
282        return $this->head;
283    }
284
285    function finalizeConverter($c)
286    {
287        LoggerLog::debug("LoggerPatternParser::finalizeConverter() with char '$c'");   
288
289        $pc = null;
290        switch($c) {
291            case 'c':
292                $pc = new LoggerCategoryPatternConverter($this->formattingInfo, $this->extractPrecisionOption());
293                LoggerLog::debug("LoggerPatternParser::finalizeConverter() CATEGORY converter.");
294                // $this->formattingInfo->dump();
295                $this->currentLiteral = '';
296                break;
297            case 'C':
298                $pc = new LoggerClassNamePatternConverter($this->formattingInfo, $this->extractPrecisionOption());
299                LoggerLog::debug("LoggerPatternParser::finalizeConverter() CLASSNAME converter.");
300                //$this->formattingInfo->dump();
301                $this->currentLiteral = '';
302                break;
303            case 'd':
304                $dateFormatStr = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601; // ISO8601_DATE_FORMAT;
305                $dOpt = $this->extractOption();
306
307                if($dOpt !== null)
308                    $dateFormatStr = $dOpt;
309                   
310                if ($dateFormatStr == 'ISO8601') {
311                    $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601;
312                } elseif($dateFormatStr == 'ABSOLUTE') {
313                    $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ABSOLUTE;
314                } elseif($dateFormatStr == 'DATE') {
315                    $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_DATE;
316                } else {
317                    $df = $dateFormatStr;
318                    if ($df == null) {
319                        $df = LOG4PHP_LOGGER_PATTERN_PARSER_DATE_FORMAT_ISO8601;
320                    }
321                }
322                $pc = new LoggerDatePatternConverter($this->formattingInfo, $df);
323                $this->currentLiteral = '';
324                break;
325            case 'F':
326                $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_FILE_LOCATION_CONVERTER);
327                LoggerLog::debug("LoggerPatternParser::finalizeConverter() File name converter.");
328                //formattingInfo.dump();
329                $this->currentLiteral = '';
330                break;
331            case 'l':
332                $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_FULL_LOCATION_CONVERTER);
333                LoggerLog::debug("LoggerPatternParser::finalizeConverter() Location converter.");
334                //formattingInfo.dump();
335                $this->currentLiteral = '';
336                break;
337            case 'L':
338                $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_LINE_LOCATION_CONVERTER);
339                LoggerLog::debug("LoggerPatternParser::finalizeConverter() LINE NUMBER converter.");
340                //formattingInfo.dump();
341                $this->currentLiteral = '';
342                break;
343            case 'm':
344                $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_MESSAGE_CONVERTER);
345                LoggerLog::debug("LoggerPatternParser::finalizeConverter() MESSAGE converter.");
346                //formattingInfo.dump();
347                $this->currentLiteral = '';
348                break;
349            case 'M':
350                $pc = new LoggerLocationPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_METHOD_LOCATION_CONVERTER);
351                //LogLog.debug("METHOD converter.");
352                //formattingInfo.dump();
353                $this->currentLiteral = '';
354                break;
355            case 'p':
356                $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_LEVEL_CONVERTER);
357                //LogLog.debug("LEVEL converter.");
358                //formattingInfo.dump();
359                $this->currentLiteral = '';
360                break;
361            case 'r':
362                $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_RELATIVE_TIME_CONVERTER);
363                LoggerLog::debug("LoggerPatternParser::finalizeConverter() RELATIVE TIME converter.");
364                //formattingInfo.dump();
365                $this->currentLiteral = '';
366                break;
367            case 't':
368                $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_THREAD_CONVERTER);
369                LoggerLog::debug("LoggerPatternParser::finalizeConverter() THREAD converter.");
370                //formattingInfo.dump();
371                $this->currentLiteral = '';
372                break;
373            case 'u':
374                if($this->i < $this->patternLength) {
375                    $cNext = $this->pattern{$this->i};
376                    if(ord($cNext) >= ord('0') and ord($cNext) <= ord('9')) {
377                        $pc = new LoggerUserFieldPatternConverter($this->formattingInfo, (string)(ord($cNext) - ord('0')));
378                        LoggerLog::debug("LoggerPatternParser::finalizeConverter() USER converter [{$cNext}].");
379                        // formattingInfo.dump();
380                        $this->currentLiteral = '';
381                        $this->i++;
382                    } else {
383                        LoggerLog::warn("LoggerPatternParser::finalizeConverter() Unexpected char '{$cNext}' at position {$this->i}.");
384                    }
385                }
386                break;
387            case 'x':
388                $pc = new LoggerBasicPatternConverter($this->formattingInfo, LOG4PHP_LOGGER_PATTERN_PARSER_NDC_CONVERTER);
389                LoggerLog::debug("LoggerPatternParser::finalizeConverter() NDC converter.");
390                $this->currentLiteral = '';
391                break;
392
393            case 'X':
394                $xOpt = $this->extractOption();
395                $pc = new LoggerMDCPatternConverter($this->formattingInfo, $xOpt);
396                LoggerLog::debug("LoggerPatternParser::finalizeConverter() MDC converter.");
397                $this->currentLiteral = '';
398                break;
399            default:
400                LoggerLog::warn("LoggerPatternParser::finalizeConverter() Unexpected char [$c] at position {$this->i} in conversion pattern.");
401                $pc = new LoggerLiteralPatternConverter($this->currentLiteral);
402                $this->currentLiteral = '';
403        }
404        $this->addConverter($pc);
405    }
406
407    function addConverter($pc)
408    {
409        $this->currentLiteral = '';
410        // Add the pattern converter to the list.
411        $this->addToList($pc);
412        // Next pattern is assumed to be a literal.
413        $this->state = LOG4PHP_LOGGER_PATTERN_PARSER_LITERAL_STATE;
414        // Reset formatting info
415        $this->formattingInfo->reset();
416    }
417}
418
419?>
Note: See TracBrowser for help on using the repository browser.