385 * @exception SecurityException if a security manager exists and if
386 * the caller does not have <tt>LoggingPermission("control")</tt>.
387 * @exception IllegalArgumentException if {@code limit < 0}, or {@code count < 1}.
388 * @exception IllegalArgumentException if pattern is an empty string
389 *
390 */
391 public FileHandler(String pattern, int limit, int count, boolean append)
392 throws IOException, SecurityException {
393 if (limit < 0 || count < 1 || pattern.length() < 1) {
394 throw new IllegalArgumentException();
395 }
396 checkPermission();
397 configure();
398 this.pattern = pattern;
399 this.limit = limit;
400 this.count = count;
401 this.append = append;
402 openFiles();
403 }
404
405 /**
406 * Open the set of output files, based on the configured
407 * instance variables.
408 */
409 private void openFiles() throws IOException {
410 LogManager manager = LogManager.getLogManager();
411 manager.checkPermission();
412 if (count < 1) {
413 throw new IllegalArgumentException("file count = " + count);
414 }
415 if (limit < 0) {
416 limit = 0;
417 }
418
419 // We register our own ErrorManager during initialization
420 // so we can record exceptions.
421 InitializationErrorManager em = new InitializationErrorManager();
422 setErrorManager(em);
423
424 // Create a lock file. This grants us exclusive access
441 // object. Try again.
442 continue;
443 }
444
445 final Path lockFilePath = Paths.get(lockFileName);
446 FileChannel channel = null;
447 int retries = -1;
448 boolean fileCreated = false;
449 while (channel == null && retries++ < 1) {
450 try {
451 channel = FileChannel.open(lockFilePath,
452 CREATE_NEW, WRITE);
453 fileCreated = true;
454 } catch (FileAlreadyExistsException ix) {
455 // This may be a zombie file left over by a previous
456 // execution. Reuse it - but only if we can actually
457 // write to its directory.
458 // Note that this is a situation that may happen,
459 // but not too frequently.
460 if (Files.isRegularFile(lockFilePath, LinkOption.NOFOLLOW_LINKS)
461 && Files.isWritable(lockFilePath.getParent())) {
462 try {
463 channel = FileChannel.open(lockFilePath,
464 WRITE, APPEND);
465 } catch (NoSuchFileException x) {
466 // Race condition - retry once, and if that
467 // fails again just try the next name in
468 // the sequence.
469 continue;
470 } catch(IOException x) {
471 // the file may not be writable for us.
472 // try the next name in the sequence
473 break;
474 }
475 } else {
476 // at this point channel should still be null.
477 // break and try the next name in the sequence.
478 break;
479 }
480 }
481 }
|
385 * @exception SecurityException if a security manager exists and if
386 * the caller does not have <tt>LoggingPermission("control")</tt>.
387 * @exception IllegalArgumentException if {@code limit < 0}, or {@code count < 1}.
388 * @exception IllegalArgumentException if pattern is an empty string
389 *
390 */
391 public FileHandler(String pattern, int limit, int count, boolean append)
392 throws IOException, SecurityException {
393 if (limit < 0 || count < 1 || pattern.length() < 1) {
394 throw new IllegalArgumentException();
395 }
396 checkPermission();
397 configure();
398 this.pattern = pattern;
399 this.limit = limit;
400 this.count = count;
401 this.append = append;
402 openFiles();
403 }
404
405 private boolean isParentWritable(Path path) {
406 Path parent = path.getParent();
407 if (parent == null) {
408 parent = path.toAbsolutePath().getParent();
409 }
410 return parent != null && Files.isWritable(parent);
411 }
412
413 /**
414 * Open the set of output files, based on the configured
415 * instance variables.
416 */
417 private void openFiles() throws IOException {
418 LogManager manager = LogManager.getLogManager();
419 manager.checkPermission();
420 if (count < 1) {
421 throw new IllegalArgumentException("file count = " + count);
422 }
423 if (limit < 0) {
424 limit = 0;
425 }
426
427 // We register our own ErrorManager during initialization
428 // so we can record exceptions.
429 InitializationErrorManager em = new InitializationErrorManager();
430 setErrorManager(em);
431
432 // Create a lock file. This grants us exclusive access
449 // object. Try again.
450 continue;
451 }
452
453 final Path lockFilePath = Paths.get(lockFileName);
454 FileChannel channel = null;
455 int retries = -1;
456 boolean fileCreated = false;
457 while (channel == null && retries++ < 1) {
458 try {
459 channel = FileChannel.open(lockFilePath,
460 CREATE_NEW, WRITE);
461 fileCreated = true;
462 } catch (FileAlreadyExistsException ix) {
463 // This may be a zombie file left over by a previous
464 // execution. Reuse it - but only if we can actually
465 // write to its directory.
466 // Note that this is a situation that may happen,
467 // but not too frequently.
468 if (Files.isRegularFile(lockFilePath, LinkOption.NOFOLLOW_LINKS)
469 && isParentWritable(lockFilePath)) {
470 try {
471 channel = FileChannel.open(lockFilePath,
472 WRITE, APPEND);
473 } catch (NoSuchFileException x) {
474 // Race condition - retry once, and if that
475 // fails again just try the next name in
476 // the sequence.
477 continue;
478 } catch(IOException x) {
479 // the file may not be writable for us.
480 // try the next name in the sequence
481 break;
482 }
483 } else {
484 // at this point channel should still be null.
485 // break and try the next name in the sequence.
486 break;
487 }
488 }
489 }
|