[jboss-svn-commits] JBoss Common SVN: r3328 - jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Fri Jul 3 00:07:47 EDT 2009
Author: david.lloyd at jboss.com
Date: 2009-07-03 00:07:45 -0400 (Fri, 03 Jul 2009)
New Revision: 3328
Added:
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/PeriodicRotatingFileHandler.java
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/WriterHandler.java
Modified:
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/ExtHandler.java
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/FileHandler.java
jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/OutputStreamHandler.java
Log:
Handlers: javadoc, cleanup refactor of stream/writer handlers, add periodic rotating file handler
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java 2009-07-03 01:49:43 UTC (rev 3327)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/AsyncHandler.java 2009-07-03 04:07:45 UTC (rev 3328)
@@ -31,7 +31,11 @@
import java.util.logging.Handler;
import java.util.logging.ErrorManager;
-public final class AsyncHandler extends ExtHandler {
+/**
+ * An asycnhronous log handler which is used to write to a handler or group of handlers which are "slow" or introduce
+ * some degree of latency.
+ */
+public class AsyncHandler extends ExtHandler {
private final CopyOnWriteArrayList<Handler> handlers = new CopyOnWriteArrayList<Handler>();
private final ThreadFactory threadFactory;
@@ -43,23 +47,47 @@
private static final int DEFAULT_QUEUE_LENGTH = 512;
+ /**
+ * Construct a new instance.
+ *
+ * @param queueLength the queue length
+ * @param threadFactory the thread factory to use to construct the handler thread
+ */
public AsyncHandler(final int queueLength, final ThreadFactory threadFactory) {
recordQueue = new ArrayQueue<ExtLogRecord>(queueLength);
this.threadFactory = threadFactory;
}
+ /**
+ * Construct a new instance.
+ *
+ * @param threadFactory the thread factory to use to construct the handler thread
+ */
public AsyncHandler(final ThreadFactory threadFactory) {
this(DEFAULT_QUEUE_LENGTH, threadFactory);
}
+ /**
+ * Construct a new instance.
+ *
+ * @param queueLength the queue length
+ */
public AsyncHandler(final int queueLength) {
this(queueLength, Executors.defaultThreadFactory());
}
+ /**
+ * Construct a new instance.
+ */
public AsyncHandler() {
this(DEFAULT_QUEUE_LENGTH);
}
+ /**
+ * Add a sub-handler to publish events to.
+ *
+ * @param handler the sub-handler
+ */
public void addHandler(final Handler handler) {
checkAccess();
synchronized (recordQueue) {
@@ -70,6 +98,11 @@
}
}
+ /**
+ * Remove a sub-handler.
+ *
+ * @param handler the sub-handler
+ */
public void removeHandler(final Handler handler) {
checkAccess();
synchronized (recordQueue) {
@@ -79,6 +112,7 @@
}
}
+ /** {@inheritDoc} */
public void publish(final ExtLogRecord record) {
final Queue<ExtLogRecord> recordQueue = this.recordQueue;
boolean intr = Thread.interrupted();
@@ -115,12 +149,14 @@
}
}
+ /** {@inheritDoc} */
public void flush() {
for (Handler handler : handlers) {
handler.flush();
}
}
+ /** {@inheritDoc} */
public void close() throws SecurityException {
checkAccess();
closed = true;
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/ExtHandler.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/ExtHandler.java 2009-07-03 01:49:43 UTC (rev 3327)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/ExtHandler.java 2009-07-03 04:07:45 UTC (rev 3328)
@@ -62,7 +62,7 @@
*
* @throws SecurityException if a security manager is installed and the caller does not have the {@code "control" LoggingPermission}
*/
- protected void checkAccess() throws SecurityException {
+ protected static void checkAccess() throws SecurityException {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(CONTROL_PERMISSION);
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/FileHandler.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/FileHandler.java 2009-07-03 01:49:43 UTC (rev 3327)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/FileHandler.java 2009-07-03 04:07:45 UTC (rev 3328)
@@ -26,11 +26,15 @@
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
+import java.util.logging.Formatter;
+
/**
* A simple file handler.
*/
public class FileHandler extends OutputStreamHandler {
+ private File file;
+
/**
* Construct a new instance with no formatter and no output file.
*/
@@ -38,22 +42,68 @@
}
/**
+ * Construct a new instance with the given formatter and no output file.
+ *
+ * @param formatter the formatter
+ */
+ public FileHandler(final Formatter formatter) {
+ super(formatter);
+ }
+
+ /**
+ * Construct a new instance with the given formatter and output file.
+ *
+ * @param formatter the formatter
+ * @param file the file
+ * @throws FileNotFoundException if the file could not be found on open
+ */
+ public FileHandler(final Formatter formatter, final File file) throws FileNotFoundException {
+ super(formatter);
+ setFile(file);
+ }
+
+ /**
* Set the output file.
*
* @param file the file
* @throws FileNotFoundException if an error occurs opening the file
*/
public void setFile(File file) throws FileNotFoundException {
- final File parentFile = file.getParentFile();
- if (parentFile != null) {
- parentFile.mkdirs();
+ synchronized (outputLock) {
+ if (file == null) {
+ setOutputStream(null);
+ }
+ final File parentFile = file.getParentFile();
+ if (parentFile != null) {
+ parentFile.mkdirs();
+ }
+ boolean ok = false;
+ final FileOutputStream fos = new FileOutputStream(file, false);
+ try {
+ setOutputStream(fos);
+ this.file = file;
+ } finally {
+ if (! ok) {
+ safeClose(fos);
+ }
+ }
}
- setOutputStream(new FileOutputStream(file, false));
}
/**
- * Set the output file.
+ * Get the current output file.
*
+ * @return the file
+ */
+ public File getFile() {
+ synchronized (outputLock) {
+ return file;
+ }
+ }
+
+ /**
+ * Set the output file by name.
+ *
* @param fileName the file name
* @throws FileNotFoundException if an error occurs opening the file
*/
Modified: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/OutputStreamHandler.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/OutputStreamHandler.java 2009-07-03 01:49:43 UTC (rev 3327)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/OutputStreamHandler.java 2009-07-03 04:07:45 UTC (rev 3328)
@@ -22,31 +22,22 @@
package org.jboss.logmanager.handlers;
-import org.jboss.logmanager.ExtLogRecord;
import org.jboss.logmanager.formatters.Formatters;
import java.io.OutputStream;
-import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
-import java.io.IOException;
-import java.io.Closeable;
-import java.io.Flushable;
-import java.security.Permission;
+import java.io.Writer;
import java.util.logging.ErrorManager;
import java.util.logging.Formatter;
-import java.util.logging.LoggingPermission;
/**
- * An output stream handler that supports autoflush and extended log records. No records will be logged until an
- * output stream is configured.
+ * An output stream handler which supports any {@code OutputStream}, using the specified encoding. If no encoding is
+ * specified, the platform default is used.
*/
-public class OutputStreamHandler extends ExtHandler {
+public class OutputStreamHandler extends WriterHandler {
- private volatile boolean autoFlush = false;
- private final Object outputLock = new Object();
private OutputStream outputStream;
- private Writer writer;
/**
* Construct a new instance with no formatter.
@@ -76,173 +67,50 @@
}
/**
- * Determine whether autoflush is currently enabled.
- *
- * @return {@code true} if autoflush is enabled
- */
- public boolean isAutoFlush() {
- return autoFlush;
- }
-
- /**
- * Change the autoflush status.
- *
- * @param autoFlush {@code true} to enable autoflush, {@code false} to disable it
- * @throws SecurityException if you do not have sufficient permission to invoke this operation
- */
- public void setAutoFlush(final boolean autoFlush) throws SecurityException {
- checkControl();
- this.autoFlush = autoFlush;
- }
-
- /**
* Set the target encoding.
*
* @param encoding the new encoding
* @throws SecurityException if you do not have sufficient permission to invoke this operation
- * @throws UnsupportedEncodingException if the specified encoding is not supported
+ * @throws java.io.UnsupportedEncodingException if the specified encoding is not supported
*/
public void setEncoding(final String encoding) throws SecurityException, UnsupportedEncodingException {
- checkControl();
+ // superclass checks access
super.setEncoding(encoding);
synchronized (outputLock) {
- final Writer writer = this.writer;
- if (writer == null) {
- return;
- }
- closeWriter();
- this.writer = encoding == null ? new OutputStreamWriter(outputStream) : new OutputStreamWriter(outputStream, encoding);
+ final OutputStream outputStream = this.outputStream;
+ updateWriter(outputStream, encoding);
}
}
+ /** {@inheritDoc} Setting a writer will replace any target output stream. */
+ public void setWriter(final Writer writer) {
+ synchronized (outputLock) {
+ super.setWriter(writer);
+ outputStream = null;
+ }
+ }
+
/**
* Set the output stream to write to.
*
- * @param newOutputStream the new output stream or {@code null} for none
+ * @param outputStream the new output stream or {@code null} for none
*/
- public void setOutputStream(final OutputStream newOutputStream) {
- checkControl();
- if (newOutputStream == null) {
- closeStream();
- return;
- }
- final Writer newWriter;
+ public void setOutputStream(final OutputStream outputStream) {
+ checkAccess();
try {
- final String encoding = getEncoding();
- newWriter = encoding == null ? new OutputStreamWriter(newOutputStream) : new OutputStreamWriter(newOutputStream, encoding);
+ synchronized (outputLock) {
+ this.outputStream = outputStream;
+ updateWriter(outputStream, getEncoding());
+ }
} catch (UnsupportedEncodingException e) {
throw new IllegalArgumentException("The specified encoding is invalid");
} catch (Exception e) {
- reportError("Error opeing output stream", e, ErrorManager.OPEN_FAILURE);
+ reportError("Error opening output stream", e, ErrorManager.OPEN_FAILURE);
return;
}
- synchronized (outputLock) {
- closeStream();
- outputStream = newOutputStream;
- writer = newWriter;
- try {
- writer.write(getFormatter().getHead(this));
- } catch (Exception e) {
- reportError("Error writing section header", e, ErrorManager.WRITE_FAILURE);
- }
- }
}
- /**
- * Publish a log record.
- *
- * @param record the log record to publish
- */
- public void publish(final ExtLogRecord record) {
- if (isLoggable(record)) {
- final String formatted;
- final Formatter formatter = getFormatter();
- try {
- formatted = formatter.format(record);
- } catch (Exception ex) {
- reportError("Formatting error", ex, ErrorManager.FORMAT_FAILURE);
- return;
- }
- try {
- synchronized (outputLock) {
- final Writer writer = this.writer;
- if (writer == null) {
- return;
- }
- writer.write(formatted);
- }
- } catch (Exception ex) {
- reportError("Error writing log message", ex, ErrorManager.WRITE_FAILURE);
- return;
- }
- if (autoFlush) flush();
- }
+ private void updateWriter(final OutputStream newOutputStream, final String encoding) throws UnsupportedEncodingException {
+ setWriter(newOutputStream == null ? null : encoding == null ? new OutputStreamWriter(newOutputStream) : new OutputStreamWriter(newOutputStream, encoding));
}
-
- /**
- * Flush this logger.
- */
- public void flush() {
- synchronized (outputLock) {
- safeFlush(writer);
- }
- }
-
- private void safeClose(Closeable c) {
- try {
- if (c != null) c.close();
- } catch (Exception e) {
- reportError("Error closing resource", e, ErrorManager.CLOSE_FAILURE);
- }
- }
-
- private void safeFlush(Flushable f) {
- try {
- if (f != null) f.flush();
- } catch (IOException e) {
- reportError("Error on flush", e, ErrorManager.FLUSH_FAILURE);
- }
- }
-
- private void closeWriter() {
- safeFlush(writer);
- writer = null;
- }
-
- private void closeStream() {
- synchronized (outputLock) {
- final Writer writer = this.writer;
- if (writer == null) {
- return;
- }
- try {
- writer.write(getFormatter().getTail(this));
- } catch (Exception ex) {
- reportError("Error writing section tail", ex, ErrorManager.WRITE_FAILURE);
- }
- safeFlush(writer);
- safeClose(writer);
- this.writer = null;
- outputStream = null;
- }
- }
-
- /**
- * Close this logger.
- *
- * @throws SecurityException if you do not have sufficient permission to invoke this operation
- */
- public void close() throws SecurityException {
- checkControl();
- closeStream();
- }
-
- private static void checkControl() throws SecurityException {
- final SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(CONTROL_PERMISSION);
- }
- }
-
- private static final Permission CONTROL_PERMISSION = new LoggingPermission("control", null);
}
Added: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/PeriodicRotatingFileHandler.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/PeriodicRotatingFileHandler.java (rev 0)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/PeriodicRotatingFileHandler.java 2009-07-03 04:07:45 UTC (rev 3328)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.logmanager.handlers;
+
+import org.jboss.logmanager.ExtLogRecord;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Calendar;
+import java.io.File;
+import java.io.FileNotFoundException;
+
+import java.util.logging.ErrorManager;
+
+/**
+ * A file handler which rotates the log at a preset time interval. The interval is determined by the content of the
+ * suffix string which is passed in to {@link #setSuffix(String)}.
+ */
+public class PeriodicRotatingFileHandler extends FileHandler {
+
+ private SimpleDateFormat format;
+ private String nextSuffix;
+ private Period period;
+ private long nextRollover;
+
+ /** {@inheritDoc} This implementation checks to see if the scheduled rollover time has yet occurred. */
+ protected void preWrite(final ExtLogRecord record) {
+ final long recordMillis = record.getMillis();
+ if (recordMillis >= nextRollover) {
+ rollOver();
+ calcNextRollover(recordMillis);
+ }
+ }
+
+ /**
+ * Set the suffix string. The string is in a format which can be understood by {@link java.text.SimpleDateFormat}.
+ * The period of the rotation is automatically calculated based on the suffix.
+ *
+ * @param suffix the suffix
+ * @throws IllegalArgumentException if the suffix is not valid
+ */
+ public void setSuffix(String suffix) throws IllegalArgumentException {
+ final SimpleDateFormat format = new SimpleDateFormat(suffix);
+ final int len = suffix.length();
+ Period period = Period.NEVER;
+ for (int i = 0; i < len; i ++) {
+ switch (suffix.charAt(i)) {
+ case 'y': period = min(period, Period.YEAR); break;
+ case 'M': period = min(period, Period.MONTH); break;
+ case 'w':
+ case 'W': period = min(period, Period.WEEK); break;
+ case 'D':
+ case 'd':
+ case 'F':
+ case 'E': period = min(period, Period.DAY); break;
+ case 'a': period = min(period, Period.HALF_DAY); break;
+ case 'H':
+ case 'k':
+ case 'K':
+ case 'h': period = min(period, Period.HOUR); break;
+ case 'm': period = min(period, Period.MINUTE); break;
+ case '\'': while (suffix.charAt(++i) != '\''); break;
+ case 's':
+ case 'S': throw new IllegalArgumentException("Rotating by second or millisecond is not supported");
+ }
+ }
+ synchronized (outputLock) {
+ this.format = format;
+ this.period = period;
+ final long now = System.currentTimeMillis();
+ calcNextRollover(now);
+ }
+ }
+
+ private void rollOver() {
+ try {
+ final File file = getFile();
+ // first, close the original file (some OSes won't let you move/rename a file that is open)
+ setFile(null);
+ // next, rotate it
+ file.renameTo(new File(file.getName() + nextSuffix));
+ // start new file
+ setFile(file);
+ } catch (FileNotFoundException e) {
+ reportError("Unable to rotate log file", e, ErrorManager.OPEN_FAILURE);
+ }
+ }
+
+ private void calcNextRollover(final long fromTime) {
+ if (period == Period.NEVER) {
+ nextRollover = Long.MAX_VALUE;
+ return;
+ }
+ nextSuffix = format.format(new Date(fromTime));
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(fromTime);
+ final Period period = this.period;
+ // clear out less-significant fields
+ switch (period) {
+ default:
+ case YEAR:
+ calendar.clear(Calendar.MONTH);
+ case MONTH:
+ calendar.clear(Calendar.DAY_OF_MONTH);
+ calendar.clear(Calendar.WEEK_OF_MONTH);
+ case WEEK:
+ calendar.clear(Calendar.DAY_OF_WEEK);
+ calendar.clear(Calendar.DAY_OF_WEEK_IN_MONTH);
+ case DAY:
+ calendar.clear(Calendar.HOUR_OF_DAY);
+ case HALF_DAY:
+ calendar.clear(Calendar.HOUR);
+ case HOUR:
+ calendar.clear(Calendar.MINUTE);
+ case MINUTE:
+ calendar.clear(Calendar.SECOND);
+ calendar.clear(Calendar.MILLISECOND);
+ }
+ // increment the relevant field
+ switch (period) {
+ case YEAR:
+ calendar.add(Calendar.YEAR, 1);
+ break;
+ case MONTH:
+ calendar.add(Calendar.MONTH, 1);
+ break;
+ case WEEK:
+ calendar.add(Calendar.WEEK_OF_YEAR, 1);
+ break;
+ case DAY:
+ calendar.add(Calendar.DAY_OF_MONTH, 1);
+ break;
+ case HALF_DAY:
+ calendar.add(Calendar.AM_PM, 1);
+ break;
+ case HOUR:
+ calendar.add(Calendar.HOUR, 1);
+ break;
+ case MINUTE:
+ calendar.add(Calendar.MINUTE, 1);
+ break;
+ }
+ nextRollover = calendar.getTimeInMillis();
+ }
+
+ private static <T extends Comparable<? super T>> T min(T a, T b) {
+ return a.compareTo(b) <= 0 ? a : b;
+ }
+
+ /**
+ * Possible period values. Keep in strictly ascending order of magnitude.
+ */
+ public enum Period {
+ MINUTE,
+ HOUR,
+ HALF_DAY,
+ DAY,
+ WEEK,
+ MONTH,
+ YEAR,
+ NEVER,
+ }
+}
Added: jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/WriterHandler.java
===================================================================
--- jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/WriterHandler.java (rev 0)
+++ jboss-logmanager/trunk/src/main/java/org/jboss/logmanager/handlers/WriterHandler.java 2009-07-03 04:07:45 UTC (rev 3328)
@@ -0,0 +1,165 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.logmanager.handlers;
+
+import java.io.Writer;
+import java.io.Closeable;
+import java.io.Flushable;
+import java.io.IOException;
+
+import java.util.logging.ErrorManager;
+import java.util.logging.Formatter;
+
+import org.jboss.logmanager.ExtLogRecord;
+
+/**
+ * A handler which writes to any {@code Writer}.
+ */
+public class WriterHandler extends ExtHandler {
+
+ protected final Object outputLock = new Object();
+ private Writer writer;
+
+ /**
+ * Publish a log record.
+ *
+ * @param record the log record to publish
+ */
+ public void publish(final ExtLogRecord record) {
+ if (isLoggable(record)) {
+ final String formatted;
+ final Formatter formatter = getFormatter();
+ try {
+ formatted = formatter.format(record);
+ } catch (Exception ex) {
+ reportError("Formatting error", ex, ErrorManager.FORMAT_FAILURE);
+ return;
+ }
+ try {
+ synchronized (outputLock) {
+ final Writer writer = this.writer;
+ if (writer == null) {
+ return;
+ }
+ preWrite(record);
+ writer.write(formatted);
+ }
+ } catch (Exception ex) {
+ reportError("Error writing log message", ex, ErrorManager.WRITE_FAILURE);
+ return;
+ }
+ }
+ }
+
+ /**
+ * Execute any pre-write policy, such as file rotation. The write lock is held during this method, so make
+ * it quick. The default implementation does nothing.
+ *
+ * @param record the record about to be logged
+ */
+ protected void preWrite(final ExtLogRecord record) {
+ // do nothing by default
+ }
+
+ /**
+ * Set the writer. The writer will then belong to this handler; when the handler is closed or a new writer is set,
+ * this writer will be closed.
+ *
+ * @param writer the new writer, or {@code null} to disable logging
+ */
+ public void setWriter(final Writer writer) {
+ checkAccess();
+ final Writer oldWriter;
+ synchronized (outputLock) {
+ oldWriter = this.writer;
+ writeTail(oldWriter);
+ safeFlush(oldWriter);
+ writeHead(writer);
+ this.writer = writer;
+ }
+ if (oldWriter != null) {
+ safeClose(oldWriter);
+ }
+ }
+
+ private void writeHead(final Writer writer) {
+ if (writer != null) {
+ try {
+ writer.write(getFormatter().getHead(this));
+ } catch (Exception e) {
+ reportError("Error writing section header", e, ErrorManager.WRITE_FAILURE);
+ }
+ }
+ }
+
+ private void writeTail(final Writer writer) {
+ if (writer != null) {
+ try {
+ writer.write(getFormatter().getTail(this));
+ } catch (Exception ex) {
+ reportError("Error writing section tail", ex, ErrorManager.WRITE_FAILURE);
+ }
+ }
+ }
+
+ /**
+ * Flush this logger.
+ */
+ public void flush() {
+ // todo - maybe this synch is not really needed... if there's a perf detriment, drop it
+ synchronized (outputLock) {
+ safeFlush(writer);
+ }
+ }
+
+ /**
+ * Close this logger.
+ *
+ * @throws SecurityException if the caller does not have sufficient permission
+ */
+ public void close() throws SecurityException {
+ checkAccess();
+ setWriter(null);
+ }
+
+ /**
+ * Safely close the resource, reporting an error if the close fails.
+ *
+ * @param c the resource
+ */
+ protected void safeClose(Closeable c) {
+ try {
+ if (c != null) c.close();
+ } catch (Exception e) {
+ reportError("Error closing resource", e, ErrorManager.CLOSE_FAILURE);
+ }
+ }
+
+ private void safeFlush(Flushable f) {
+ try {
+ if (f != null) f.flush();
+ } catch (IOException e) {
+ reportError("Error on flush", e, ErrorManager.FLUSH_FAILURE);
+ }
+ }
+}
More information about the jboss-svn-commits
mailing list