X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar_unused%2Forg%2Fapache%2Flog4j%2FWriterAppender.java;fp=srcjar_unused%2Forg%2Fapache%2Flog4j%2FWriterAppender.java;h=1c93cc256ef515f73b73826509257ee8feb634b8;hb=65740880573a48adc758bec3939ece9d9ae104dd;hp=0000000000000000000000000000000000000000;hpb=71aa78b8a7d54e5aeb6b278310dfd735efb77477;p=jalview.git diff --git a/srcjar_unused/org/apache/log4j/WriterAppender.java b/srcjar_unused/org/apache/log4j/WriterAppender.java new file mode 100644 index 0000000..1c93cc2 --- /dev/null +++ b/srcjar_unused/org/apache/log4j/WriterAppender.java @@ -0,0 +1,389 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.log4j; + +import java.io.IOException; +import java.io.InterruptedIOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; + +import org.apache.log4j.helpers.LogLog; +import org.apache.log4j.helpers.QuietWriter; +import org.apache.log4j.spi.ErrorHandler; +import org.apache.log4j.spi.LoggingEvent; + +// Contibutors: Jens Uwe Pipka +// Ben Sandee + +/** + WriterAppender appends log events to a {@link java.io.Writer} or an + {@link java.io.OutputStream} depending on the user's choice. + + @author Ceki Gülcü + @since 1.1 */ +public class WriterAppender extends AppenderSkeleton { + + + /** + Immediate flush means that the underlying writer or output stream + will be flushed at the end of each append operation unless shouldFlush() + is overridden. Immediate + flush is slower but ensures that each append request is actually + written. If immediateFlush is set to + false, then there is a good chance that the last few + logs events are not actually written to persistent media if and + when the application crashes. + +

The immediateFlush variable is set to + true by default. + + */ + protected boolean immediateFlush = true; + + /** + The encoding to use when writing.

The + encoding variable is set to null by + default which results in the utilization of the system's default + encoding. */ + protected String encoding; + + /** + This is the {@link QuietWriter quietWriter} where we will write + to. + */ + protected QuietWriter qw; + + + /** + This default constructor does nothing. */ + public + WriterAppender() { + } + + /** + Instantiate a WriterAppender and set the output destination to a + new {@link OutputStreamWriter} initialized with os + as its {@link OutputStream}. */ + public + WriterAppender(Layout layout, OutputStream os) { + this(layout, new OutputStreamWriter(os)); + } + + /** + Instantiate a WriterAppender and set the output destination to + writer. + +

The writer must have been previously opened by + the user. */ + public + WriterAppender(Layout layout, Writer writer) { + this.layout = layout; + this.setWriter(writer); + } + + /** + If the ImmediateFlush option is set to + true, the appender will flush at the end of each + write. This is the default behavior. If the option is set to + false, then the underlying stream can defer writing + to physical medium to a later time. + +

Avoiding the flush operation at the end of each append results in + a performance gain of 10 to 20 percent. However, there is safety + tradeoff involved in skipping flushing. Indeed, when flushing is + skipped, then it is likely that the last few log events will not + be recorded on disk when the application exits. This is a high + price to pay even for a 20% performance gain. + */ + public + void setImmediateFlush(boolean value) { + immediateFlush = value; + } + + /** + Returns value of the ImmediateFlush option. + */ + public + boolean getImmediateFlush() { + return immediateFlush; + } + + /** + Does nothing. + */ + public + void activateOptions() { + } + + + /** + This method is called by the {@link AppenderSkeleton#doAppend} + method. + +

If the output stream exists and is writable then write a log + statement to the output stream. Otherwise, write a single warning + message to System.err. + +

The format of the output will depend on this appender's + layout. + + */ + public + void append(LoggingEvent event) { + + // Reminder: the nesting of calls is: + // + // doAppend() + // - check threshold + // - filter + // - append(); + // - checkEntryConditions(); + // - subAppend(); + + if(!checkEntryConditions()) { + return; + } + subAppend(event); + } + + /** + This method determines if there is a sense in attempting to append. + +

It checks whether there is a set output target and also if + there is a set layout. If these checks fail, then the boolean + value false is returned. */ + protected + boolean checkEntryConditions() { + if(this.closed) { + LogLog.warn("Not allowed to write to a closed appender."); + return false; + } + + if(this.qw == null) { + errorHandler.error("No output stream or file set for the appender named ["+ + name+"]."); + return false; + } + + if(this.layout == null) { + errorHandler.error("No layout set for the appender named ["+ name+"]."); + return false; + } + return true; + } + + + /** + Close this appender instance. The underlying stream or writer is + also closed. + +

Closed appenders cannot be reused. + + @see #setWriter + @since 0.8.4 */ + public + synchronized + void close() { + if(this.closed) { + return; + } + this.closed = true; + writeFooter(); + reset(); + } + + /** + * Close the underlying {@link java.io.Writer}. + * */ + protected void closeWriter() { + if(qw != null) { + try { + qw.close(); + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + // There is do need to invoke an error handler at this late + // stage. + LogLog.error("Could not close " + qw, e); + } + } + } + + /** + Returns an OutputStreamWriter when passed an OutputStream. The + encoding used will depend on the value of the + encoding property. If the encoding value is + specified incorrectly the writer will be opened using the default + system encoding (an error message will be printed to the loglog. */ + protected + OutputStreamWriter createWriter(OutputStream os) { + OutputStreamWriter retval = null; + + String enc = getEncoding(); + if(enc != null) { + try { + retval = new OutputStreamWriter(os, enc); + } catch(IOException e) { + if (e instanceof InterruptedIOException) { + Thread.currentThread().interrupt(); + } + LogLog.warn("Error initializing output writer."); + LogLog.warn("Unsupported encoding?"); + } + } + if(retval == null) { + retval = new OutputStreamWriter(os); + } + return retval; + } + + public String getEncoding() { + return encoding; + } + + public void setEncoding(String value) { + encoding = value; + } + + + + + /** + Set the {@link ErrorHandler} for this WriterAppender and also the + underlying {@link QuietWriter} if any. */ + public synchronized void setErrorHandler(ErrorHandler eh) { + if(eh == null) { + LogLog.warn("You have tried to set a null error-handler."); + } else { + this.errorHandler = eh; + if(this.qw != null) { + this.qw.setErrorHandler(eh); + } + } + } + + /** +

Sets the Writer where the log output will go. The + specified Writer must be opened by the user and be + writable. + +

The java.io.Writer will be closed when the + appender instance is closed. + + +

WARNING: Logging to an unopened Writer will fail. +

+ @param writer An already opened Writer. */ + public synchronized void setWriter(Writer writer) { + reset(); + this.qw = new QuietWriter(writer, errorHandler); + //this.tp = new TracerPrintWriter(qw); + writeHeader(); + } + + + /** + Actual writing occurs here. + +

Most subclasses of WriterAppender will need to + override this method. + + @since 0.9.0 */ + protected + void subAppend(LoggingEvent event) { + this.qw.write(this.layout.format(event)); + + if(layout.ignoresThrowable()) { + String[] s = event.getThrowableStrRep(); + if (s != null) { + int len = s.length; + for(int i = 0; i < len; i++) { + this.qw.write(s[i]); + this.qw.write(Layout.LINE_SEP); + } + } + } + + if(shouldFlush(event)) { + this.qw.flush(); + } + } + + + + /** + The WriterAppender requires a layout. Hence, this method returns + true. + */ + public + boolean requiresLayout() { + return true; + } + + /** + Clear internal references to the writer and other variables. + + Subclasses can override this method for an alternate closing + behavior. */ + protected + void reset() { + closeWriter(); + this.qw = null; + //this.tp = null; + } + + + /** + Write a footer as produced by the embedded layout's {@link + Layout#getFooter} method. */ + protected + void writeFooter() { + if(layout != null) { + String f = layout.getFooter(); + if(f != null && this.qw != null) { + this.qw.write(f); + this.qw.flush(); + } + } + } + + /** + Write a header as produced by the embedded layout's {@link + Layout#getHeader} method. */ + protected + void writeHeader() { + if(layout != null) { + String h = layout.getHeader(); + if(h != null && this.qw != null) { + this.qw.write(h); + } + } + } + + /** + * Determines whether the writer should be flushed after + * this event is written. + * + * @since 1.2.16 + */ + protected boolean shouldFlush(final LoggingEvent event) { + return immediateFlush; + } +}