1 7 8 package java.util.logging; 9 10 import java.io.*; 11 import java.nio.channels.FileChannel ; 12 import java.nio.channels.FileLock ; 13 import java.security.*; 14 15 102 103 public class FileHandler extends StreamHandler { 104 private MeteredStream meter; 105 private boolean append; 106 private int limit; private int count; 108 private String pattern; 109 private String lockFileName; 110 private FileOutputStream lockStream; 111 private File files[]; 112 private static final int MAX_LOCKS = 100; 113 private static java.util.HashMap locks = new java.util.HashMap (); 114 115 private class MeteredStream extends OutputStream { 119 OutputStream out; 120 int written; 121 122 MeteredStream(OutputStream out, int written) { 123 this.out = out; 124 this.written = written; 125 } 126 127 public void write(int b) throws IOException { 128 out.write(b); 129 written++; 130 } 131 132 public void write(byte buff[]) throws IOException { 133 out.write(buff); 134 written += buff.length; 135 } 136 137 public void write(byte buff[], int off, int len) throws IOException { 138 out.write(buff,off,len); 139 written += len; 140 } 141 142 public void flush() throws IOException { 143 out.flush(); 144 } 145 146 public void close() throws IOException { 147 out.close(); 148 } 149 } 150 151 private void open(File fname, boolean append) throws IOException { 152 int len = 0; 153 if (append) { 154 len = (int)fname.length(); 155 } 156 FileOutputStream fout = new FileOutputStream(fname.toString(), append); 157 BufferedOutputStream bout = new BufferedOutputStream(fout); 158 meter = new MeteredStream(bout, len); 159 setOutputStream(meter); 160 } 161 162 private void configure() { 166 LogManager manager = LogManager.getLogManager(); 167 168 String cname = getClass().getName(); 169 170 pattern = manager.getStringProperty(cname + ".pattern", "%h/java%u.log"); 171 limit = manager.getIntProperty(cname + ".limit", 0); 172 if (limit < 0) { 173 limit = 0; 174 } 175 count = manager.getIntProperty(cname + ".count", 1); 176 if (count <= 0) { 177 count = 1; 178 } 179 append = manager.getBooleanProperty(cname + ".append", false); 180 setLevel(manager.getLevelProperty(cname + ".level", Level.ALL)); 181 setFilter(manager.getFilterProperty(cname + ".filter", null)); 182 setFormatter(manager.getFormatterProperty(cname + ".formatter", new XMLFormatter ())); 183 try { 184 setEncoding(manager.getStringProperty(cname +".encoding", null)); 185 } catch (Exception ex) { 186 try { 187 setEncoding(null); 188 } catch (Exception ex2) { 189 } 192 } 193 } 194 195 196 205 public FileHandler() throws IOException, SecurityException { 206 checkAccess(); 207 configure(); 208 openFiles(); 209 } 210 211 228 public FileHandler(String pattern) throws IOException, SecurityException { 229 if (pattern.length() < 1 ) { 230 throw new IllegalArgumentException (); 231 } 232 checkAccess(); 233 configure(); 234 this.pattern = pattern; 235 this.limit = 0; 236 this.count = 1; 237 openFiles(); 238 } 239 240 260 public FileHandler(String pattern, boolean append) throws IOException, SecurityException { 261 if (pattern.length() < 1 ) { 262 throw new IllegalArgumentException (); 263 } 264 checkAccess(); 265 configure(); 266 this.pattern = pattern; 267 this.limit = 0; 268 this.count = 1; 269 this.append = append; 270 openFiles(); 271 } 272 273 296 public FileHandler(String pattern, int limit, int count) 297 throws IOException, SecurityException { 298 if (limit < 0 || count < 1 || pattern.length() < 1) { 299 throw new IllegalArgumentException (); 300 } 301 checkAccess(); 302 configure(); 303 this.pattern = pattern; 304 this.limit = limit; 305 this.count = count; 306 openFiles(); 307 } 308 309 335 public FileHandler(String pattern, int limit, int count, boolean append) 336 throws IOException, SecurityException { 337 if (limit < 0 || count < 1 || pattern.length() < 1) { 338 throw new IllegalArgumentException (); 339 } 340 checkAccess(); 341 configure(); 342 this.pattern = pattern; 343 this.limit = limit; 344 this.count = count; 345 this.append = append; 346 openFiles(); 347 } 348 349 private void openFiles() throws IOException { 352 LogManager manager = LogManager.getLogManager(); 353 manager.checkAccess(); 354 if (count < 1) { 355 throw new IllegalArgumentException ("file count = " + count); 356 } 357 if (limit < 0) { 358 limit = 0; 359 } 360 361 InitializationErrorManager em = new InitializationErrorManager(); 364 setErrorManager(em); 365 366 int unique = -1; 369 for (;;) { 370 unique++; 371 if (unique > MAX_LOCKS) { 372 throw new IOException("Couldn't get lock for " + pattern); 373 } 374 lockFileName = generate(pattern, 0, unique).toString() + ".lck"; 376 synchronized(locks) { 381 if (locks.get(lockFileName) != null) { 382 continue; 385 } 386 FileChannel fc; 387 try { 388 lockStream = new FileOutputStream(lockFileName); 389 fc = lockStream.getChannel(); 390 } catch (IOException ix) { 391 continue; 394 } 395 try { 396 FileLock fl = fc.tryLock(); 397 if (fl == null) { 398 continue; 400 } 401 } catch (IOException ix) { 403 } 408 locks.put(lockFileName, lockFileName); 410 break; 411 } 412 } 413 414 files = new File[count]; 415 for (int i = 0; i < count; i++) { 416 files[i] = generate(pattern, i, unique); 417 } 418 419 if (append) { 421 open(files[0], true); 422 } else { 423 rotate(); 424 } 425 426 Exception ex = em.lastException; 428 if (ex != null) { 429 if (ex instanceof IOException) { 430 throw (IOException) ex; 431 } else if (ex instanceof SecurityException ) { 432 throw (SecurityException ) ex; 433 } else { 434 throw new IOException("Exception: " + ex); 435 } 436 } 437 438 setErrorManager(new ErrorManager ()); 440 } 441 442 private File generate(String pattern, int generation, int unique) throws IOException { 444 File file = null; 445 String word = ""; 446 int ix = 0; 447 boolean sawg = false; 448 boolean sawu = false; 449 while (ix < pattern.length()) { 450 char ch = pattern.charAt(ix); 451 ix++; 452 char ch2 = 0; 453 if (ix < pattern.length()) { 454 ch2 = Character.toLowerCase(pattern.charAt(ix)); 455 } 456 if (ch == '/') { 457 if (file == null) { 458 file = new File(word); 459 } else { 460 file = new File(file, word); 461 } 462 word = ""; 463 continue; 464 } else if (ch == '%') { 465 if (ch2 == 't') { 466 String tmpDir = System.getProperty("java.io.tmpdir"); 467 if (tmpDir == null) { 468 tmpDir = System.getProperty("user.home"); 469 } 470 file = new File(tmpDir); 471 ix++; 472 word = ""; 473 continue; 474 } else if (ch2 == 'h') { 475 file = new File(System.getProperty("user.home")); 476 if (isSetUID()) { 477 throw new IOException("can't use %h in set UID program"); 480 } 481 ix++; 482 word = ""; 483 continue; 484 } else if (ch2 == 'g') { 485 word = word + generation; 486 sawg = true; 487 ix++; 488 continue; 489 } else if (ch2 == 'u') { 490 word = word + unique; 491 sawu = true; 492 ix++; 493 continue; 494 } else if (ch2 == '%') { 495 word = word + "%"; 496 ix++; 497 continue; 498 } 499 } 500 word = word + ch; 501 } 502 if (count > 1 && !sawg) { 503 word = word + "." + generation; 504 } 505 if (unique > 0 && !sawu) { 506 word = word + "." + unique; 507 } 508 if (word.length() > 0) { 509 if (file == null) { 510 file = new File(word); 511 } else { 512 file = new File(file, word); 513 } 514 } 515 return file; 516 } 517 518 private synchronized void rotate() { 520 Level oldLevel = getLevel(); 521 setLevel(Level.OFF); 522 523 super.close(); 524 for (int i = count-2; i >= 0; i--) { 525 File f1 = files[i]; 526 File f2 = files[i+1]; 527 if (f1.exists()) { 528 if (f2.exists()) { 529 f2.delete(); 530 } 531 f1.renameTo(f2); 532 } 533 } 534 try { 535 open(files[0], false); 536 } catch (IOException ix) { 537 reportError(null, ix, ErrorManager.OPEN_FAILURE); 540 541 } 542 setLevel(oldLevel); 543 } 544 545 551 public synchronized void publish(LogRecord record) { 552 if (!isLoggable(record)) { 553 return; 554 } 555 super.publish(record); 556 flush(); 557 if (limit > 0 && meter.written >= limit) { 558 AccessController.doPrivileged(new PrivilegedAction() { 564 public Object run() { 565 rotate(); 566 return null; 567 } 568 }); 569 } 570 } 571 572 578 public synchronized void close() throws SecurityException { 579 super.close(); 580 if (lockFileName == null) { 582 return; 583 } 584 try { 585 lockStream.close(); 588 } catch (Exception ex) { 589 } 591 synchronized(locks) { 592 locks.remove(lockFileName); 593 } 594 new File(lockFileName).delete(); 595 lockFileName = null; 596 lockStream = null; 597 } 598 599 private static class InitializationErrorManager extends ErrorManager { 600 Exception lastException; 601 public void error(String msg, Exception ex, int code) { 602 lastException = ex; 603 } 604 } 605 606 private static native boolean isSetUID(); 608 } 609 610 | Popular Tags |