1 22 23 package org.gjt.sp.util; 24 25 import java.io.*; 26 import java.util.*; 27 import javax.swing.*; 28 import javax.swing.event.*; 29 30 46 public class Log 47 { 48 53 public static final int MAXLINES = 500; 54 55 60 public static final int DEBUG = 1; 61 62 67 public static final int MESSAGE = 3; 68 69 74 public static final int NOTICE = 5; 75 76 81 public static final int WARNING = 7; 82 83 88 public static final int ERROR = 9; 89 91 100 public static void init(boolean stdio, int level) 101 { 102 if(stdio) 103 { 104 if(System.out == realOut && System.err == realErr) 105 { 106 System.setOut(createPrintStream(NOTICE,null)); 107 System.setErr(createPrintStream(ERROR,null)); 108 } 109 } 110 111 Log.level = level; 112 113 log(MESSAGE,Log.class,"When reporting bugs, please" 115 + " include the following information:"); 116 String [] props = { 117 "java.version", "java.vm.version", "java.runtime.version", 118 "java.vendor", "java.compiler", "os.name", "os.version", 119 "os.arch", "user.home", "java.home", 120 "java.class.path", 121 }; 122 for(int i = 0; i < props.length; i++) 123 { 124 log(MESSAGE,Log.class, 125 props[i] + '=' + System.getProperty(props[i])); 126 } 127 } 129 137 public static void setLogWriter(Writer stream) 138 { 139 if(Log.stream == null && stream != null) 140 { 141 try 142 { 143 if(wrap) 144 { 145 for(int i = logLineCount; i < log.length; i++) 146 { 147 stream.write(log[i]); 148 stream.write(lineSep); 149 } 150 } 151 for(int i = 0; i < logLineCount; i++) 152 { 153 stream.write(log[i]); 154 stream.write(lineSep); 155 } 156 157 stream.flush(); 158 } 159 catch(Exception e) 160 { 161 } 163 } 164 165 Log.stream = stream; 166 } 168 173 public static void flushStream() 174 { 175 if(stream != null) 176 { 177 try 178 { 179 stream.flush(); 180 } 181 catch(IOException io) 182 { 183 io.printStackTrace(realErr); 184 } 185 } 186 } 188 193 public static void closeStream() 194 { 195 if(stream != null) 196 { 197 try 198 { 199 stream.close(); 200 stream = null; 201 } 202 catch(IOException io) 203 { 204 io.printStackTrace(realErr); 205 } 206 } 207 } 209 214 public static ListModel getLogListModel() 215 { 216 return listModel; 217 } 219 230 public static void log(int urgency, Object source, Object message, 231 Throwable exception) 232 { 233 log(urgency,source,message); 235 log(urgency,source,exception); 236 } 238 261 public static void log(int urgency, Object source, Object message) 262 { 263 String _source; 264 if(source == null) 265 { 266 _source = Thread.currentThread().getName(); 267 if(_source == null) 268 { 269 _source = Thread.currentThread().getClass().getName(); 270 } 271 } 272 else if(source instanceof Class ) 273 _source = ((Class )source).getName(); 274 else 275 _source = source.getClass().getName(); 276 int index = _source.lastIndexOf('.'); 277 if(index != -1) 278 _source = _source.substring(index+1); 279 280 if(message instanceof Throwable ) 281 { 282 _logException(urgency,source,(Throwable )message); 283 } 284 else 285 { 286 String _message = String.valueOf(message); 287 synchronized(LOCK) 290 { 291 StringTokenizer st = new StringTokenizer( 292 _message,"\r\n"); 293 int lineCount = 0; 294 boolean oldWrap = wrap; 295 while(st.hasMoreTokens()) 296 { 297 lineCount++; 298 _log(urgency,_source,st.nextToken() 299 .replace('\t',' ')); 300 } 301 listModel.update(lineCount,oldWrap); 302 } 303 } 304 } 306 308 private static final Object LOCK = new Object (); 310 private static final String [] log; 311 private static int logLineCount; 312 private static boolean wrap; 313 private static int level = WARNING; 314 private static Writer stream; 315 private static final String lineSep; 316 private static final PrintStream realOut; 317 private static final PrintStream realErr; 318 private static final LogListModel listModel; 319 321 static 323 { 324 level = WARNING; 325 326 realOut = System.out; 327 realErr = System.err; 328 329 log = new String [MAXLINES]; 330 lineSep = System.getProperty("line.separator"); 331 listModel = new LogListModel(); 332 } 334 private static PrintStream createPrintStream(final int urgency, 336 final Object source) 337 { 338 return new LogPrintStream(urgency, source); 339 } 341 private static void _logException(final int urgency, 343 final Object source, 344 final Throwable message) 345 { 346 PrintStream out = createPrintStream(urgency,source); 347 348 synchronized(LOCK) 349 { 350 message.printStackTrace(out); 351 } 352 } 354 private static void _log(int urgency, String source, String message) 356 { 357 String fullMessage = '[' + urgencyToString(urgency) + "] " + source 358 + ": " + message; 359 360 try 361 { 362 log[logLineCount] = fullMessage; 363 if(++logLineCount >= log.length) 364 { 365 wrap = true; 366 logLineCount = 0; 367 } 368 369 if(stream != null) 370 { 371 stream.write(fullMessage); 372 stream.write(lineSep); 373 } 374 } 375 catch(Exception e) 376 { 377 e.printStackTrace(realErr); 378 } 379 380 if(urgency >= level) 381 { 382 if(urgency == ERROR) 383 realErr.println(fullMessage); 384 else 385 realOut.println(fullMessage); 386 } 387 } 389 private static String urgencyToString(int urgency) 391 { 392 switch(urgency) 393 { 394 case DEBUG: 395 return "debug"; 396 case MESSAGE: 397 return "message"; 398 case NOTICE: 399 return "notice"; 400 case WARNING: 401 return "warning"; 402 case ERROR: 403 return "error"; 404 } 405 406 throw new IllegalArgumentException ("Invalid urgency: " + urgency); 407 } 409 411 static class LogListModel implements ListModel 413 { 414 final List<ListDataListener> listeners = new ArrayList<ListDataListener>(); 415 416 private void fireIntervalAdded(int index1, int index2) 417 { 418 for(int i = 0; i < listeners.size(); i++) 419 { 420 ListDataListener listener = listeners.get(i); 421 listener.intervalAdded(new ListDataEvent(this, 422 ListDataEvent.INTERVAL_ADDED, 423 index1,index2)); 424 } 425 } 426 427 private void fireIntervalRemoved(int index1, int index2) 428 { 429 for(int i = 0; i < listeners.size(); i++) 430 { 431 ListDataListener listener = listeners.get(i); 432 listener.intervalRemoved(new ListDataEvent(this, 433 ListDataEvent.INTERVAL_REMOVED, 434 index1,index2)); 435 } 436 } 437 438 public void addListDataListener(ListDataListener listener) 439 { 440 listeners.add(listener); 441 } 442 443 public void removeListDataListener(ListDataListener listener) 444 { 445 listeners.remove(listener); 446 } 447 448 public Object getElementAt(int index) 449 { 450 if(wrap) 451 { 452 if(index < MAXLINES - logLineCount) 453 return log[index + logLineCount]; 454 else 455 return log[index - MAXLINES + logLineCount]; 456 } 457 else 458 return log[index]; 459 } 460 461 public int getSize() 462 { 463 if(wrap) 464 return MAXLINES; 465 else 466 return logLineCount; 467 } 468 469 void update(final int lineCount, final boolean oldWrap) 470 { 471 if(lineCount == 0 || listeners.isEmpty()) 472 return; 473 474 SwingUtilities.invokeLater(new Runnable () 475 { 476 public void run() 477 { 478 if(wrap) 479 { 480 if(oldWrap) 481 fireIntervalRemoved(0,lineCount - 1); 482 else 483 { 484 fireIntervalRemoved(0, 485 logLineCount); 486 } 487 fireIntervalAdded( 488 MAXLINES - lineCount + 1, 489 MAXLINES); 490 } 491 else 492 { 493 fireIntervalAdded( 494 logLineCount - lineCount + 1, 495 logLineCount); 496 } 497 } 498 }); 499 } 500 } 502 508 private static class LogPrintStream extends PrintStream { 509 510 private final ByteArrayOutputStream buffer; 511 private final OutputStream orig; 512 513 LogPrintStream(int urgency, Object source) 514 { 515 super(new LogOutputStream(urgency, source)); 516 buffer = new ByteArrayOutputStream(); 517 orig = out; 518 } 519 520 530 public PrintStream printf(String format, Object ... args) 531 { 532 synchronized (orig) 533 { 534 buffer.reset(); 535 out = buffer; 536 super.printf(format, args); 537 538 try 539 { 540 byte[] data = buffer.toByteArray(); 541 orig.write(data, 0, data.length); 542 out = orig; 543 } 544 catch (IOException ioe) 545 { 546 } 548 finally 549 { 550 buffer.reset(); 551 } 552 } 553 return this; 554 } 555 } 556 557 private static class LogOutputStream extends OutputStream 558 { 559 private final int urgency; 560 private final Object source; 561 562 LogOutputStream(int urgency, Object source) 563 { 564 this.urgency = urgency; 565 this.source = source; 566 } 567 568 public synchronized void write(int b) 569 { 570 byte[] barray = { (byte)b }; 571 write(barray,0,1); 572 } 573 574 public synchronized void write(byte[] b, int off, int len) 575 { 576 String str = new String (b,off,len); 577 log(urgency,source,str); 578 } 579 } 580 581 } 582 583 | Popular Tags |