1 52 53 package com.go.trove.log; 54 55 import java.lang.ref.WeakReference ; 56 import java.io.*; 57 import java.util.*; 58 59 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 93 public synchronized void startAutoRollover() { 94 if (mRolloverThread == null) { 97 mRolloverThread = new Thread (new AutoRollover(this), nextName()); 98 mRolloverThread.setDaemon(true); 99 mRolloverThread.start(); 100 } 101 } 102 103 107 public synchronized void stopAutoRollover() { 108 if (mRolloverThread != null) { 109 mRolloverThread.interrupt(); 110 mRolloverThread = null; 111 } 112 } 113 114 117 protected abstract void moveToIntervalStart(Calendar cal); 118 119 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 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 198 private static class AutoRollover implements Runnable { 199 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 stream.getOutputStream(); 220 } 221 catch (IOException e) { 222 } 223 224 Calendar cal = Calendar.getInstance(); 225 stream.moveToNextIntervalStart(cal); 226 227 stream = null; 230 231 long calTime = cal.getTime().getTime(); 232 long timeLeft = calTime - System.currentTimeMillis(); 233 234 while (timeLeft > 0) { 235 Thread.sleep(timeLeft); 237 timeLeft = calTime - System.currentTimeMillis(); 238 } 239 } 240 } 241 catch (InterruptedException e) { 242 } 244 } 245 } 246 } 247 | Popular Tags |