source: branches/comu-ver2/data/module/log4php/php5/log4php/helpers/LoggerPatternParser.php @ 18220

Revision 18220, 17.7 KB checked in by yokkuns, 15 years ago (diff)

#149 ロガークラス作成

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