📄 patternformatter.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 file. */package org.jivesoftware.util.log.format;import org.jivesoftware.util.FastDateFormat;import org.jivesoftware.util.log.ContextMap;import org.jivesoftware.util.log.LogEvent;import org.jivesoftware.util.log.Priority;import java.io.StringWriter;import java.util.Date;import java.util.Stack;/** * This formater formats the LogEvents according to a input pattern * string. * <p/> * The format of each pattern element can be %[+|-][#[.#]]{field:subformat}. * </p> * <ul> * <li>The +|- indicates left or right justify. * </li> * <li>The #.# indicates the minimum and maximum size of output.<br> * You may omit the values and the field will be formatted without size * restriction.<br> * You may specify '#', or '#.' to define an minimum size, only.</br> * You may specify '.#' to define an maximum size only. * </li> * <li> * 'field' indicates which field is to be output and must be one of * properties of LogEvent.<br> * Currently following fields are supported: * <dl> * <dt>category</dt> * <dd>Category value of the logging event.</dd> * <dt>context</dt> * <dd>Context value of the logging event.</dd> * <dt>message</dt> * <dd>Message value of the logging event.</dd> * <dt>time</dt> * <dd>Time value of the logging event.</dd> * <dt>rtime</dt> * <dd>Relative time value of the logging event.</dd> * <dt>throwable</dt> * <dd>Throwable value of the logging event.</dd> * <dt>priority</dt> * <dd>Priority value of the logging event.</dd> * </dl> * </li> * <li>'subformat' indicates a particular subformat and is currently only used * for category context to specify the context map parameter name. * </li> * </ul> * <p>A simple example of a typical PatternFormatter format: * </p> * <pre><code>%{time} %5.5{priority}[%-10.10{category}]: %{message} * </pre></code> * <p/> * This format string will format a log event printing first time value of * of log event with out size restriction, next priority with minum and maximum size 5, * next category right justified having minmum and maximum size of 10, * at last the message of the log event without size restriction. * </p> * <p>A formatted sample message of the above pattern format: * </p> * <pre><code>1000928827905 DEBUG [ junit]: Sample message * </pre><code> * * @author <a href="mailto:peter@apache.org">Peter Donald</a> * @author <a href="mailto:sylvain@apache.org">Sylvain Wallez</a> * @version CVS $Revision: 1747 $ $Date: 2005-08-04 14:36:36 -0700 (Thu, 04 Aug 2005) $ */public class PatternFormatter implements Formatter { private final static int TYPE_TEXT = 1; private final static int TYPE_CATEGORY = 2; private final static int TYPE_CONTEXT = 3; private final static int TYPE_MESSAGE = 4; private final static int TYPE_TIME = 5; private final static int TYPE_RELATIVE_TIME = 6; private final static int TYPE_THROWABLE = 7; private final static int TYPE_PRIORITY = 8; /** * The maximum value used for TYPEs. Subclasses can define their own TYPEs * starting at <code>MAX_TYPE + 1</code>. */ protected final static int MAX_TYPE = TYPE_PRIORITY; private final static String TYPE_CATEGORY_STR = "category"; private final static String TYPE_CONTEXT_STR = "context"; private final static String TYPE_MESSAGE_STR = "message"; private final static String TYPE_TIME_STR = "time"; private final static String TYPE_RELATIVE_TIME_STR = "rtime"; private final static String TYPE_THROWABLE_STR = "throwable"; private final static String TYPE_PRIORITY_STR = "priority"; private final static String SPACE_16 = " "; private final static String SPACE_8 = " "; private final static String SPACE_4 = " "; private final static String SPACE_2 = " "; private final static String SPACE_1 = " "; private final static String EOL = System.getProperty("line.separator", "\n"); protected static class PatternRun { public String m_data; public boolean m_rightJustify; public int m_minSize; public int m_maxSize; public int m_type; public String m_format; } private PatternRun m_formatSpecification[]; private FastDateFormat m_simpleDateFormat; private final Date m_date = new Date(); /** * @deprecated Use constructor PatternFormatter(String pattern) as this does not * correctly initialize object */ public PatternFormatter() { } public PatternFormatter(final String pattern) { parse(pattern); } /** * Extract and build a pattern from input string. * * @param stack the stack on which to place patterns * @param pattern the input string * @param index the start of pattern run * @return the number of characters in pattern run */ private int addPatternRun(final Stack stack, final char pattern[], int index) { final PatternRun run = new PatternRun(); final int start = index++; //first check for a +|- sign if ('+' == pattern[index]) index++; else if ('-' == pattern[index]) { run.m_rightJustify = true; index++; } if (Character.isDigit(pattern[index])) { int total = 0; while (Character.isDigit(pattern[index])) { total = total * 10 + (pattern[index] - '0'); index++; } run.m_minSize = total; } //check for . sign indicating a maximum is to follow if (index < pattern.length && '.' == pattern[index]) { index++; if (Character.isDigit(pattern[index])) { int total = 0; while (Character.isDigit(pattern[index])) { total = total * 10 + (pattern[index] - '0'); index++; } run.m_maxSize = total; } } if (index >= pattern.length || '{' != pattern[index]) { throw new IllegalArgumentException("Badly formed pattern at character " + index); } int typeStart = index; while (index < pattern.length && pattern[index] != ':' && pattern[index] != '}') { index++; } int typeEnd = index - 1; final String type = new String(pattern, typeStart + 1, typeEnd - typeStart); run.m_type = getTypeIdFor(type); if (index < pattern.length && pattern[index] == ':') { index++; while (index < pattern.length && pattern[index] != '}') index++; final int length = index - typeEnd - 2; if (0 != length) { run.m_format = new String(pattern, typeEnd + 2, length); } } if (index >= pattern.length || '}' != pattern[index]) { throw new IllegalArgumentException("Unterminated type in pattern at character " + index); } index++; stack.push(run); return index - start; } /** * Extract and build a text run from input string. * It does special handling of '\n' and '\t' replaceing * them with newline and tab. * * @param stack the stack on which to place runs * @param pattern the input string * @param index the start of the text run * @return the number of characters in run */ private int addTextRun(final Stack stack, final char pattern[], int index) { final PatternRun run = new PatternRun(); final int start = index; boolean escapeMode = false; if ('%' == pattern[index]) index++; final StringBuffer sb = new StringBuffer(); while (index < pattern.length && pattern[index] != '%') { if (escapeMode) { if ('n' == pattern[index]) sb.append(EOL); else if ('t' == pattern[index]) sb.append('\t'); else sb.append(pattern[index]); escapeMode = false; } else if ('\\' == pattern[index]) escapeMode = true; else sb.append(pattern[index]); index++; } run.m_data = sb.toString(); run.m_type = TYPE_TEXT; stack.push(run); return index - start; } /** * Utility to append a string to buffer given certain constraints. * * @param sb the StringBuffer * @param minSize the minimum size of output (0 to ignore) * @param maxSize the maximum size of output (0 to ignore) * @param rightJustify true if the string is to be right justified in it's box. * @param output the input string */ private void append(final StringBuffer sb, final int minSize, final int maxSize, final boolean rightJustify, final String output) { final int size = output.length(); if (size < minSize) { //assert( minSize > 0 ); if (rightJustify) { appendWhiteSpace(sb, minSize - size); sb.append(output); } else { sb.append(output); appendWhiteSpace(sb, minSize - size); } } else if (maxSize > 0 && maxSize < size) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -