KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > cjdbc > common > util > LoggingOutputStream


1 /**
2  * C-JDBC: Clustered JDBC.
3  * Copyright (C) 2002-2004 French National Institute For Research In Computer
4  * Science And Control (INRIA).
5  * Contact: c-jdbc@objectweb.org
6  *
7  * This library is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU Lesser General Public License as published by the
9  * Free Software Foundation; either version 2.1 of the License, or any later
10  * version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this library; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
20  *
21  * Initial developer(s): Jim Moore
22  * Contributor(s): Nicolas Modrzyk
23  */

24
25 package org.objectweb.cjdbc.common.util;
26
27 import java.io.IOException JavaDoc;
28 import java.io.OutputStream JavaDoc;
29
30 import org.apache.log4j.Category;
31 import org.apache.log4j.Priority;
32
33 /**
34  * An OutputStream that flushes out to a Category.
35  * <p>
36  * Note that no data is written out to the Category until the stream is flushed
37  * or closed.
38  * <p>
39  *
40  * @author <a HREF="mailto://Jim.Moore@rocketmail.com">Jim Moore</a>
41  * @author <a HREF="mailto:Nicolas.Modrzyk@inrialpes.fr">Nicolas Modrzyk</a>
42  *
43  * @see Category
44  */

45 public class LoggingOutputStream extends OutputStream JavaDoc
46 {
47   protected static final String JavaDoc LINE_SEPERATOR = System
48                                                           .getProperty("line.separator");
49   /**
50    * Used to maintain the contract of {@link #close()}.
51    */

52   protected boolean hasBeenClosed = false;
53   /**
54    * The internal buffer where data is stored.
55    */

56   protected byte[] buf;
57   /**
58    * The number of valid bytes in the buffer. This value is always in the range
59    * <tt>0</tt> through <tt>buf.length</tt>; elements <tt>buf[0]</tt>
60    * through <tt>buf[count-1]</tt> contain valid byte data.
61    */

62   protected int count;
63   /**
64    * Remembers the size of the buffer for speed.
65    */

66   private int bufLength;
67   /**
68    * The default number of bytes in the buffer. =2048
69    */

70   public static final int DEFAULT_BUFFER_LENGTH = 2048;
71   /**
72    * The category to write to.
73    */

74   protected Category category;
75   /**
76    * The priority to use when writing to the Category.
77    */

78   protected Priority priority;
79
80   private LoggingOutputStream()
81   {
82     // illegal
83
}
84
85   /**
86    * Creates the LoggingOutputStream to flush to the given Category.
87    *
88    * @param cat the Category to write to
89    * @param priority the Priority to use when writing to the Category
90    * @exception IllegalArgumentException if cat == null or priority == null
91    */

92   public LoggingOutputStream(Category cat, Priority priority)
93       throws IllegalArgumentException JavaDoc
94   {
95     if (cat == null)
96     {
97       throw new IllegalArgumentException JavaDoc("cat == null");
98     }
99     if (priority == null)
100     {
101       throw new IllegalArgumentException JavaDoc("priority == null");
102     }
103     this.priority = priority;
104     category = cat;
105     bufLength = DEFAULT_BUFFER_LENGTH;
106     buf = new byte[DEFAULT_BUFFER_LENGTH];
107     count = 0;
108   }
109
110   /**
111    * Closes this output stream and releases any system resources associated
112    * with this stream. The general contract of <code>close</code> is that it
113    * closes the output stream. A closed stream cannot perform output operations
114    * and cannot be reopened.
115    */

116   public void close()
117   {
118     flush();
119     hasBeenClosed = true;
120   }
121
122   /**
123    * Writes the specified byte to this output stream. The general contract for
124    * <code>write</code> is that one byte is written to the output stream. The
125    * byte to be written is the eight low-order bits of the argument <code>b</code>.
126    * The 24 high-order bits of <code>b</code> are ignored.
127    *
128    * @param b the <code>byte</code> to write
129    * @exception IOException if an I/O error occurs. In particular, an <code>IOException</code>
130    * may be thrown if the output stream has been closed.
131    */

132   public void write(final int b) throws IOException JavaDoc
133   {
134     if (hasBeenClosed)
135     {
136       throw new IOException JavaDoc("The stream has been closed.");
137     }
138     // don't log nulls
139
if (b == 0)
140     {
141       return;
142     }
143     // would this be writing past the buffer?
144
if (count == bufLength)
145     {
146       // grow the buffer
147
final int newBufLength = bufLength + DEFAULT_BUFFER_LENGTH;
148       final byte[] newBuf = new byte[newBufLength];
149       System.arraycopy(buf, 0, newBuf, 0, bufLength);
150       buf = newBuf;
151       bufLength = newBufLength;
152     }
153     buf[count] = (byte) b;
154     count++;
155   }
156
157   /**
158    * Flushes this output stream and forces any buffered output bytes to be
159    * written out. The general contract of <code>flush</code> is that calling
160    * it is an indication that, if any bytes previously written have been
161    * buffered by the implementation of the output stream, such bytes should
162    * immediately be written to their intended destination.
163    */

164   public void flush()
165   {
166     if (count == 0)
167     {
168       return;
169     }
170     // don't print out blank lines; flushing from PrintStream puts out these
171
if (count == LINE_SEPERATOR.length())
172     {
173       if (((char) buf[0]) == LINE_SEPERATOR.charAt(0) && ((count == 1) || // <-
174
// Unix
175
// &
176
// Mac,
177
// ->
178
// Windows
179
((count == 2) && ((char) buf[1]) == LINE_SEPERATOR.charAt(1))))
180       {
181         reset();
182         return;
183       }
184     }
185     final byte[] theBytes = new byte[count];
186     System.arraycopy(buf, 0, theBytes, 0, count);
187     
188     // ADDED: We don't want blank lines at all
189
String JavaDoc bytes = new String JavaDoc(theBytes).trim();
190     int line = -1;
191     while((line = bytes.indexOf(LINE_SEPERATOR))!=-1)
192     {
193         bytes = bytes.substring(0, line) + bytes.substring(line+LINE_SEPERATOR.length());
194     }
195     // END ADDED
196

197     category.log(priority, bytes);
198     reset();
199   }
200
201   private void reset()
202   {
203     // not resetting the buffer -- assuming that if it grew that it
204
// will likely grow similarly again
205
count = 0;
206   }
207 }
Popular Tags