001: /* ====================================================================
002: * The Apache Software License, Version 1.1
003: *
004: * Copyright (c) 1997-2003 The Apache Software Foundation. All rights
005: * reserved.
006: *
007: * Redistribution and use in source and binary forms, with or without
008: * modification, are permitted provided that the following conditions
009: * are met:
010: *
011: * 1. Redistributions of source code must retain the above copyright
012: * notice, this list of conditions and the following disclaimer.
013: *
014: * 2. Redistributions in binary form must reproduce the above copyright
015: * notice, this list of conditions and the following disclaimer in
016: * the documentation and/or other materials provided with the
017: * distribution.
018: *
019: * 3. The end-user documentation included with the redistribution,
020: * if any, must include the following acknowledgment:
021: * "This product includes software developed by the
022: * Apache Software Foundation (http://www.apache.org/)."
023: * Alternately, this acknowledgment may appear in the software
024: * itself, if and wherever such third-party acknowledgments
025: * normally appear.
026: *
027: * 4. The names "Jakarta", "Avalon", and "Apache Software Foundation"
028: * must not be used to endorse or promote products derived from this
029: * software without prior written permission. For written
030: * permission, please contact apache@apache.org.
031: *
032: * 5. Products derived from this software may not be called "Apache",
033: * nor may "Apache" appear in their name, without prior written
034: * permission of the Apache Software Foundation.
035: *
036: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
037: * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
038: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
039: * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
040: * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
041: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
042: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
043: * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
044: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
045: * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
046: * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
047: * SUCH DAMAGE.
048: * ====================================================================
049: *
050: * This software consists of voluntary contributions made by many
051: * individuals on behalf of the Apache Software Foundation. For more
052: * information on the Apache Software Foundation, please see
053: * <http://www.apache.org/>.
054: */
055: package org.apache.log.output.io;
056:
057: import java.io.IOException;
058: import java.io.OutputStream;
059: import org.apache.log.format.Formatter;
060: import org.apache.log.output.AbstractOutputTarget;
061:
062: /**
063: * A basic target that writes to an OutputStream.
064: *
065: * @author <a href="mailto:peter@apache.org">Peter Donald</a>
066: */
067: public class StreamTarget extends AbstractOutputTarget {
068: ///OutputStream we are writing to
069: private OutputStream m_outputStream;
070:
071: /**
072: * Constructor that writes to a stream and uses a particular formatter.
073: *
074: * @param outputStream the OutputStream to write to
075: * @param formatter the Formatter to use
076: */
077: public StreamTarget(final OutputStream outputStream,
078: final Formatter formatter) {
079: super (formatter);
080:
081: if (null != outputStream) {
082: setOutputStream(outputStream);
083: open();
084: }
085: }
086:
087: /**
088: * Set the output stream.
089: * Close down old stream and write tail if appropriate.
090: *
091: * @param outputStream the new OutputStream
092: */
093: protected synchronized void setOutputStream(
094: final OutputStream outputStream) {
095: if (null == outputStream) {
096: throw new NullPointerException(
097: "outputStream property must not be null");
098: }
099:
100: m_outputStream = outputStream;
101: }
102:
103: /**
104: * Abstract method that will output event.
105: *
106: * @param data the data to be output
107: */
108: protected synchronized void write(final String data) {
109: //Cache method local version
110: //so that can be replaced in another thread
111: final OutputStream outputStream = m_outputStream;
112:
113: if (null == outputStream) {
114: final String message = "Attempted to write data '" + data
115: + "' to Null OutputStream";
116: getErrorHandler().error(message, null, null);
117: return;
118: }
119:
120: try {
121: //TODO: We should be able to specify encoding???
122: outputStream.write(data.getBytes());
123: outputStream.flush();
124: } catch (final IOException ioe) {
125: final String message = "Error writing data '" + data
126: + "' to OutputStream";
127: getErrorHandler().error(message, ioe, null);
128: }
129: }
130:
131: /**
132: * Shutdown target.
133: * Attempting to write to target after close() will cause errors to be logged.
134: *
135: */
136: public synchronized void close() {
137: super .close();
138: shutdownStream();
139: }
140:
141: /**
142: * Shutdown output stream.
143: */
144: protected synchronized void shutdownStream() {
145: final OutputStream outputStream = m_outputStream;
146: m_outputStream = null;
147:
148: try {
149: if (null != outputStream) {
150: outputStream.close();
151: }
152: } catch (final IOException ioe) {
153: getErrorHandler().error("Error closing OutputStream", ioe,
154: null);
155: }
156: }
157: }
|