1 16 package org.apache.cocoon.util.log; 17 18 import java.io.StringWriter ; 19 import java.util.Stack ; 20 21 import org.apache.commons.lang.StringUtils; 22 import org.apache.commons.lang.SystemUtils; 23 import org.apache.log.LogEvent; 24 import org.apache.log.Priority; 25 import org.apache.log.format.Formatter; 26 import org.apache.log.util.DefaultErrorHandler; 27 28 45 public class ExtensiblePatternFormatter 46 implements Formatter 47 { 48 protected final static int TYPE_TEXT = 1; 49 protected final static int TYPE_CATEGORY = 2; 50 protected final static int TYPE_MESSAGE = 4; 51 protected final static int TYPE_TIME = 5; 52 protected final static int TYPE_RELATIVE_TIME = 6; 53 protected final static int TYPE_THROWABLE = 7; 54 protected final static int TYPE_PRIORITY = 8; 55 56 60 protected final static int MAX_TYPE = 8; 61 62 protected final static String TYPE_CATEGORY_STR = "category"; 63 protected final static String TYPE_MESSAGE_STR = "message"; 64 protected final static String TYPE_TIME_STR = "time"; 65 protected final static String TYPE_RELATIVE_TIME_STR = "rtime"; 66 protected final static String TYPE_THROWABLE_STR = "throwable"; 67 protected final static String TYPE_PRIORITY_STR = "priority"; 68 69 protected static class PatternRun { 70 public String m_data; 71 public boolean m_rightJustify; 72 public int m_minSize; 73 public int m_maxSize; 74 public int m_type; 75 public String m_format; 76 } 77 78 protected PatternRun m_formatSpecification[]; 79 80 88 protected int addPatternRun(final Stack stack, final char pattern[], int index) { 89 final PatternRun run = new PatternRun(); 90 final int start = index++; 91 92 if ('+' == pattern[index]) { 94 index++; 95 } else if ('-' == pattern[index]) { 96 run.m_rightJustify = true; 97 index++; 98 } 99 100 if (Character.isDigit(pattern[index])) { 101 int total = 0; 102 while (Character.isDigit(pattern[index])) { 103 total = total * 10 + (pattern[index] - '0'); 104 index++; 105 } 106 run.m_minSize = total; 107 } 108 109 if (index < pattern.length && '.' == pattern[index]) { 111 index++; 112 if (Character.isDigit(pattern[index])) { 113 int total = 0; 114 while (Character.isDigit(pattern[index])) { 115 total = total * 10 + (pattern[ index ] - '0'); 116 index++; 117 } 118 run.m_maxSize = total; 119 } 120 } 121 122 if (index >= pattern.length || '{' != pattern[index]) { 123 throw new IllegalArgumentException ( 124 "Badly formed pattern at character " + index ); 125 } 126 127 int typeStart = index; 128 129 while (index < pattern.length && 130 pattern[index]!= ':' && pattern[index] != '}' ) { 131 index++; 132 } 133 134 int typeEnd = index - 1; 135 136 final String type = new String (pattern, typeStart + 1, typeEnd - typeStart); 137 138 run.m_type = getTypeIdFor( type ); 139 140 if (index < pattern.length && pattern[index] == ':' ) { 141 index++; 142 while (index < pattern.length && pattern[index] != '}' ) { 143 index++; 144 } 145 final int length = index - typeEnd - 2; 146 147 if (0 != length) { 148 run.m_format = new String (pattern, typeEnd + 2, length); 149 } 150 } 151 152 if (index >= pattern.length || '}' != pattern[index]) { 153 throw new IllegalArgumentException ( 154 "Unterminated type in pattern at character " + index ); 155 } 156 index++; 157 stack.push( run ); 158 return index - start; 159 } 160 161 171 protected int addTextRun( final Stack stack, final char pattern[], int index ) { 172 final PatternRun run = new PatternRun(); 173 final int start = index; 174 boolean escapeMode = false; 175 176 if ('%' == pattern[index]) { 177 index++; 178 } 179 final StringBuffer sb = new StringBuffer (); 180 while (index < pattern.length && pattern[index] != '%') { 181 if (escapeMode) { 182 if ('n' == pattern[ index ]) { 183 sb.append( SystemUtils.LINE_SEPARATOR ); 184 } else if ('t' == pattern[ index ]) { 185 sb.append( '\t' ); 186 } else { 187 sb.append( pattern[ index ] ); 188 } 189 escapeMode = false; 190 } else if ('\\' == pattern[ index ]) { 191 escapeMode = true; 192 } else { 193 sb.append( pattern[ index ] ); 194 } 195 index++; 196 } 197 run.m_data = sb.toString(); 198 run.m_type = TYPE_TEXT; 199 stack.push(run); 200 return index - start; 201 } 202 203 212 protected void append(final StringBuffer sb, final int minSize, final int maxSize, 213 final boolean rightJustify, final String output) { 214 if (output.length() < minSize) { 215 if (rightJustify) { 216 sb.append(StringUtils.leftPad(output, minSize)); 217 } else { 218 sb.append(StringUtils.rightPad(output, minSize)); 219 } 220 } else if (maxSize > 0) { 221 if (rightJustify) { 222 sb.append(StringUtils.right(output, maxSize)); 223 } else { 224 sb.append(StringUtils.left(output, maxSize)); 225 } 226 } else { 227 sb.append(output); 228 } 229 } 230 231 237 public String format(final LogEvent event) { 238 final StringBuffer sb = new StringBuffer (); 239 240 for( int i = 0; i < m_formatSpecification.length; i++ ) { 241 final PatternRun run = m_formatSpecification[i]; 242 if (run.m_type == TYPE_TEXT) { 244 sb.append(run.m_data); 245 } else { 246 final String data = formatPatternRun(event, run); 247 if (null != data) { 248 append(sb, run.m_minSize, run.m_maxSize, run.m_rightJustify, data); 249 } 250 } 251 } 252 return sb.toString(); 253 } 254 255 261 protected String formatPatternRun( final LogEvent event, final PatternRun run ) 262 { 263 String str = null; 264 265 switch (run.m_type) 266 { 267 case TYPE_RELATIVE_TIME: 268 str = getTime( event.getRelativeTime(), run.m_format ); 269 break; 270 case TYPE_TIME: 271 str = getTime( event.getTime(), run.m_format ); 272 break; 273 case TYPE_THROWABLE: 274 str = getStackTrace( event.getThrowable(), run.m_format ); 275 break; 276 case TYPE_MESSAGE: 277 str = getMessage( event.getMessage(), run.m_format ); 278 break; 279 case TYPE_CATEGORY: 280 str = getCategory( event.getCategory(), run.m_format ); 281 break; 282 case TYPE_PRIORITY: 283 str = getPriority( event.getPriority(), run.m_format ); 284 break; 285 default: 286 new DefaultErrorHandler().error("Unknown Pattern specification." + run.m_type, null, null); 287 } 288 return str; 289 } 290 291 298 protected String getCategory(final String category, final String format) { 299 return category; 300 } 301 302 305 protected String getPriority(final Priority priority, final String format) { 306 return priority.getName(); 307 } 308 309 315 protected final String fix(final String context) { 316 return context.replace( '.', '_' ); 317 } 318 319 326 protected String getMessage(final String message, final String format) { 327 return message; 328 } 329 330 337 protected String getStackTrace(final Throwable throwable, final String format) { 338 if (null != throwable) { 339 final StringWriter sw = new StringWriter (); 340 throwable.printStackTrace(new java.io.PrintWriter (sw)); 341 return sw.toString(); 342 } 343 return ""; 344 } 345 346 353 protected String getTime(final long time, final String format) { 354 return Long.toString(time); 355 } 356 357 363 protected int getTypeIdFor(final String type) { 364 if (type.equalsIgnoreCase(TYPE_CATEGORY_STR)) { 365 return TYPE_CATEGORY; 366 } else if (type.equalsIgnoreCase(TYPE_MESSAGE_STR)) { 367 return TYPE_MESSAGE; 368 } else if (type.equalsIgnoreCase(TYPE_PRIORITY_STR)) { 369 return TYPE_PRIORITY; 370 } else if (type.equalsIgnoreCase(TYPE_TIME_STR)) { 371 return TYPE_TIME; 372 } else if (type.equalsIgnoreCase(TYPE_RELATIVE_TIME_STR)) { 373 return TYPE_RELATIVE_TIME; 374 } else if (type.equalsIgnoreCase(TYPE_THROWABLE_STR)) { 375 return TYPE_THROWABLE; 376 } else { 377 throw new IllegalArgumentException ( "Unknown Type in pattern - " + type ); 378 } 379 } 380 381 386 protected void parse(final String patternString) { 387 final Stack stack = new Stack (); 388 final int size = patternString.length(); 389 final char pattern[] = new char[size]; 390 int index = 0; 391 392 patternString.getChars(0, size, pattern, 0); 393 while (index < size) { 394 if (pattern[index] == '%' && 395 !(index != size - 1 && pattern[index + 1] == '%' )) { 396 index += addPatternRun(stack, pattern, index); 397 } else { 398 index += addTextRun(stack, pattern, index); 399 } 400 } 401 final int elementCount = stack.size(); 402 m_formatSpecification = new PatternRun[elementCount]; 403 404 for (int i = 0; i < elementCount; i++) { 405 m_formatSpecification[i] = (PatternRun) stack.elementAt(i); 406 } 407 } 408 409 414 public void setFormat(final String format) { 415 parse(format); 416 } 417 } 418 | Popular Tags |