comparison src/com/go/trove/log/IntervalLogStream.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 /* ====================================================================
2 * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3 * ====================================================================
4 * The Tea Software License, Version 1.1
5 *
6 * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution,
21 * if any, must include the following acknowledgment:
22 * "This product includes software developed by the
23 * Walt Disney Internet Group (http://opensource.go.com/)."
24 * Alternately, this acknowledgment may appear in the software itself,
25 * if and wherever such third-party acknowledgments normally appear.
26 *
27 * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28 * not be used to endorse or promote products derived from this
29 * software without prior written permission. For written
30 * permission, please contact opensource@dig.com.
31 *
32 * 5. Products derived from this software may not be called "Tea",
33 * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34 * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35 * written permission of the Walt Disney Internet Group.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * For more information about Tea, please see http://opensource.go.com/.
51 */
52
53 package com.go.trove.log;
54
55 import java.lang.ref.WeakReference;
56 import java.io.*;
57 import java.util.*;
58
59 /******************************************************************************
60 * IntervalLogStream writes to an underlying OutputStream that is opened once
61 * per a specific time interval. This class forms the basis of a dated file
62 * logging mechanism.
63 *
64 * @author Brian S O'Neill
65 * @version
66 * <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 9/07/00 <!-- $-->
67 * @see DailyFileLogStream
68 */
69 public abstract class IntervalLogStream extends OutputStream {
70 private static int cCounter;
71
72 private static synchronized String nextName() {
73 return "IntervalLogStream Auto Rollover " + cCounter++;
74 }
75
76 private Factory mFactory;
77 private OutputStream mOut;
78 private boolean mIsClosed;
79
80 private Calendar mIntervalStart;
81 private Calendar mNextIntervalStart;
82
83 private Thread mRolloverThread;
84
85 public IntervalLogStream(Factory factory) {
86 mFactory = factory;
87 }
88
89 /**
90 * Starts up a thread that automatically rolls the underlying OutputStream
91 * at the beginning of the interval, even if no output is written.
92 */
93 public synchronized void startAutoRollover() {
94 // TODO: If java.util.Timer class is available, use it instead of
95 // creating a thread each time.
96 if (mRolloverThread == null) {
97 mRolloverThread = new Thread(new AutoRollover(this), nextName());
98 mRolloverThread.setDaemon(true);
99 mRolloverThread.start();
100 }
101 }
102
103 /**
104 * If the auto-rollover thread was started, calling this method will
105 * stop it.
106 */
107 public synchronized void stopAutoRollover() {
108 if (mRolloverThread != null) {
109 mRolloverThread.interrupt();
110 mRolloverThread = null;
111 }
112 }
113
114 /**
115 * Moves calendar to beginning of log interval.
116 */
117 protected abstract void moveToIntervalStart(Calendar cal);
118
119 /**
120 * Moves calendar to beginning of next log interval.
121 */
122 protected abstract void moveToNextIntervalStart(Calendar cal);
123
124 public synchronized void write(int b) throws IOException {
125 getOutputStream().write(b);
126 }
127
128 public synchronized void write(byte[] array) throws IOException {
129 getOutputStream().write(array, 0, array.length);
130 }
131
132 public synchronized void write(byte[] array, int off, int len)
133 throws IOException {
134
135 getOutputStream().write(array, off, len);
136 }
137
138 public synchronized void flush() throws IOException {
139 getOutputStream().flush();
140 }
141
142 /**
143 * Closes any underlying OutputStreams and stops the auto-rollover thread
144 * if it is running.
145 */
146 public synchronized void close() throws IOException {
147 mIsClosed = true;
148 stopAutoRollover();
149
150 if (mOut != null) {
151 mOut.close();
152 }
153 }
154
155 protected synchronized void finalize() throws IOException {
156 close();
157 }
158
159 private synchronized OutputStream getOutputStream() throws IOException {
160 if (mIsClosed) {
161 throw new IOException("LogStream is closed");
162 }
163
164 Calendar cal = Calendar.getInstance();
165
166 if (mOut == null ||
167 cal.before(mIntervalStart) || !cal.before(mNextIntervalStart)) {
168
169 if (mOut != null) {
170 mOut.close();
171 }
172
173 mOut = new BufferedOutputStream
174 (mFactory.openOutputStream(cal.getTime()));
175
176 setIntervalEndpoints(cal);
177 }
178
179 return mOut;
180 }
181
182 private void setIntervalEndpoints(Calendar cal) {
183 mIntervalStart = (Calendar)cal.clone();
184 moveToIntervalStart(mIntervalStart);
185
186 mNextIntervalStart = cal;
187 moveToNextIntervalStart(mNextIntervalStart);
188 }
189
190 public static interface Factory {
191 public OutputStream openOutputStream(Date date) throws IOException;
192 }
193
194 /**
195 * Thread that just wakes up at the proper time so that log stream
196 * rolls over even when there is no output.
197 */
198 private static class AutoRollover implements Runnable {
199 // Refer to the log stream via a weak reference so that this thread
200 // doesn't prevent it from being garbage collected.
201 private WeakReference mLogStream;
202
203 public AutoRollover(IntervalLogStream stream) {
204 mLogStream = new WeakReference(stream);
205 }
206
207 public void run() {
208 try {
209 while (!Thread.interrupted()) {
210 IntervalLogStream stream =
211 (IntervalLogStream)mLogStream.get();
212
213 if (stream == null || stream.mIsClosed) {
214 break;
215 }
216
217 try {
218 // Just requesting the stream forces a rollover.
219 stream.getOutputStream();
220 }
221 catch (IOException e) {
222 }
223
224 Calendar cal = Calendar.getInstance();
225 stream.moveToNextIntervalStart(cal);
226
227 // Clear reference to stream so that it isn't strongly
228 // reachable from this thread.
229 stream = null;
230
231 long calTime = cal.getTime().getTime();
232 long timeLeft = calTime - System.currentTimeMillis();
233
234 while (timeLeft > 0) {
235 // Sleep until next start interval. ZZZ...
236 Thread.sleep(timeLeft);
237 timeLeft = calTime - System.currentTimeMillis();
238 }
239 }
240 }
241 catch (InterruptedException e) {
242 // Exit thread.
243 }
244 }
245 }
246 }