📄 patternparser.java
字号:
/*
* Copyright (C) The Apache Software Foundation. All rights reserved.
*
* This software is published under the terms of the Apache Software License
* version 1.1, a copy of which has been included with this distribution in
* the LICENSE.txt file.
*/
package org.apache.log4j.helpers;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.helpers.AbsoluteTimeDateFormat;
import org.apache.log4j.Layout;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.LocationInfo;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
// Contributors: Nelson Minar <(nelson@monkey.org>
// Igor E. Poteryaev <jah@mail.ru>
// Reinhard Deschler <reinhard.deschler@web.de>
/**
Most of the work of the {@link org.apache.log4j.PatternLayout} class
is delegated to the PatternParser class.
<p>It is this class that parses conversion patterns and creates
a chained list of {@link OptionConverter OptionConverters}.
@author <a href=mailto:"cakalijp@Maritz.com">James P. Cakalic</a>
@author Ceki Gülcü
@author Anders Kristensen
@since 0.8.2
*/
public class PatternParser {
private static final char ESCAPE_CHAR = '%';
private static final int LITERAL_STATE = 0;
private static final int CONVERTER_STATE = 1;
private static final int MINUS_STATE = 2;
private static final int DOT_STATE = 3;
private static final int MIN_STATE = 4;
private static final int MAX_STATE = 5;
static final int FULL_LOCATION_CONVERTER = 1000;
static final int METHOD_LOCATION_CONVERTER = 1001;
static final int CLASS_LOCATION_CONVERTER = 1002;
static final int LINE_LOCATION_CONVERTER = 1003;
static final int FILE_LOCATION_CONVERTER = 1004;
static final int RELATIVE_TIME_CONVERTER = 2000;
static final int THREAD_CONVERTER = 2001;
static final int LEVEL_CONVERTER = 2002;
static final int NDC_CONVERTER = 2003;
static final int MESSAGE_CONVERTER = 2004;
int state;
protected StringBuffer currentLiteral = new StringBuffer(32);
protected int patternLength;
protected int i;
PatternConverter head;
PatternConverter tail;
protected FormattingInfo formattingInfo = new FormattingInfo();
protected String pattern;
public
PatternParser(String pattern) {
this.pattern = pattern;
patternLength = pattern.length();
state = LITERAL_STATE;
}
private
void addToList(PatternConverter pc) {
if(head == null) {
head = tail = pc;
} else {
tail.next = pc;
tail = pc;
}
}
protected
String extractOption() {
if((i < patternLength) && (pattern.charAt(i) == '{')) {
int end = pattern.indexOf('}', i);
if (end > i) {
String r = pattern.substring(i + 1, end);
i = end+1;
return r;
}
}
return null;
}
/**
The option is expected to be in decimal and positive. In case of
error, zero is returned. */
protected
int extractPrecisionOption() {
String opt = extractOption();
int r = 0;
if(opt != null) {
try {
r = Integer.parseInt(opt);
if(r <= 0) {
LogLog.error(
"Precision option (" + opt + ") isn't a positive integer.");
r = 0;
}
}
catch (NumberFormatException e) {
LogLog.error("Category option \""+opt+"\" not a decimal integer.", e);
}
}
return r;
}
public
PatternConverter parse() {
char c;
i = 0;
while(i < patternLength) {
c = pattern.charAt(i++);
switch(state) {
case LITERAL_STATE:
// In literal state, the last char is always a literal.
if(i == patternLength) {
currentLiteral.append(c);
continue;
}
if(c == ESCAPE_CHAR) {
// peek at the next char.
switch(pattern.charAt(i)) {
case ESCAPE_CHAR:
currentLiteral.append(c);
i++; // move pointer
break;
case 'n':
currentLiteral.append(Layout.LINE_SEP);
i++; // move pointer
break;
default:
if(currentLiteral.length() != 0) {
addToList(new LiteralPatternConverter(
currentLiteral.toString()));
//LogLog.debug("Parsed LITERAL converter: \""
// +currentLiteral+"\".");
}
currentLiteral.setLength(0);
currentLiteral.append(c); // append %
state = CONVERTER_STATE;
formattingInfo.reset();
}
}
else {
currentLiteral.append(c);
}
break;
case CONVERTER_STATE:
currentLiteral.append(c);
switch(c) {
case '-':
formattingInfo.leftAlign = true;
break;
case '.':
state = DOT_STATE;
break;
default:
if(c >= '0' && c <= '9') {
formattingInfo.min = c - '0';
state = MIN_STATE;
}
else
finalizeConverter(c);
} // switch
break;
case MIN_STATE:
currentLiteral.append(c);
if(c >= '0' && c <= '9')
formattingInfo.min = formattingInfo.min*10 + (c - '0');
else if(c == '.')
state = DOT_STATE;
else {
finalizeConverter(c);
}
break;
case DOT_STATE:
currentLiteral.append(c);
if(c >= '0' && c <= '9') {
formattingInfo.max = c - '0';
state = MAX_STATE;
}
else {
LogLog.error("Error occured in position "+i
+".\n Was expecting digit, instead got char \""+c+"\".");
state = LITERAL_STATE;
}
break;
case MAX_STATE:
currentLiteral.append(c);
if(c >= '0' && c <= '9')
formattingInfo.max = formattingInfo.max*10 + (c - '0');
else {
finalizeConverter(c);
state = LITERAL_STATE;
}
break;
} // switch
} // while
if(currentLiteral.length() != 0) {
addToList(new LiteralPatternConverter(currentLiteral.toString()));
//LogLog.debug("Parsed LITERAL converter: \""+currentLiteral+"\".");
}
return head;
}
protected
void finalizeConverter(char c) {
PatternConverter pc = null;
switch(c) {
case 'c':
pc = new CategoryPatternConverter(formattingInfo,
extractPrecisionOption());
//LogLog.debug("CATEGORY converter.");
//formattingInfo.dump();
currentLiteral.setLength(0);
break;
case 'C':
pc = new ClassNamePatternConverter(formattingInfo,
extractPrecisionOption());
//LogLog.debug("CLASS_NAME converter.");
//formattingInfo.dump();
currentLiteral.setLength(0);
break;
case 'd':
String dateFormatStr = AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT;
DateFormat df;
String dOpt = extractOption();
if(dOpt != null)
dateFormatStr = dOpt;
if(dateFormatStr.equalsIgnoreCase(
AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT))
df = new ISO8601DateFormat();
else if(dateFormatStr.equalsIgnoreCase(
AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT))
df = new AbsoluteTimeDateFormat();
else if(dateFormatStr.equalsIgnoreCase(
AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT))
df = new DateTimeDateFormat();
else {
try {
df = new SimpleDateFormat(dateFormatStr);
}
catch (IllegalArgumentException e) {
LogLog.error("Could not instantiate SimpleDateFormat with " +
dateFormatStr, e);
df = (DateFormat) OptionConverter.instantiateByClassName(
"org.apache.log4j.helpers.ISO8601DateFormat",
DateFormat.class, null);
}
}
pc = new DatePatternConverter(formattingInfo, df);
//LogLog.debug("DATE converter {"+dateFormatStr+"}.");
//formattingInfo.dump();
currentLiteral.setLength(0);
break;
case 'F':
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -