001 package log; 002 003 import java.io.*; 004 005 /** 006 * A stream that can be used to read and process log files. 007 * 008 * <p>The LogInputStream will take an {@link InputStream} and try to interpret the data from that stream as 009 * a log file. You can then obtain the {@link LogEntry LogEntries} in the order they were put into the log 010 * by calling {@link #readEntry}.</p> 011 * 012 * <p><code>LogInputStreams</code> can be filtered in which case you will only see the LogEntries that are 013 * {@link LogEntryFilter#accept accepted} by the {@link LogEntryFilter filter}.</p> 014 * 015 * @author Steffen Zschaler 016 * @version 2.0 14/07/1999 017 * @since v2.0 018 */ 019 public class LogInputStream extends Object implements Serializable { 020 021 /** 022 * ID for serialization. 023 */ 024 private static final long serialVersionUID = 5413255345890174061L; 025 026 /** 027 * The input stream that backs this stream. 028 */ 029 protected InputStream m_isSource; 030 031 /** 032 * The object input stream that is build on top of the input stream. This objects in this stream are 033 * expected to be {@link LogEntry LogEntries}. 034 */ 035 protected ObjectInputStream m_oisSource; 036 037 /** 038 * The filter to be applied on the stream, if any. 039 */ 040 protected LogEntryFilter m_lefFilter; 041 042 /** 043 * Create a new LogInputStream. There will be no filter. 044 * 045 * @param isSource the InputStream that is the base for this stream. 046 * 047 * @exception IOException if an error occured or the stream is not a valid log file. 048 */ 049 public LogInputStream(InputStream isSource) throws IOException { 050 this(isSource, null); 051 } 052 053 /** 054 * Create a new LogInputStream. 055 * 056 * @param isSource the InputStream that is the base for this stream. 057 * @param lef the filter to be applied on the stream. 058 * 059 * @exception IOException if an error occured or the stream is not a valid log file. 060 */ 061 public LogInputStream(InputStream isSource, LogEntryFilter lef) throws IOException { 062 063 super(); 064 065 m_isSource = isSource; 066 067 // skip the leading zero 068 m_isSource.skip(1); 069 070 m_oisSource = new ObjectInputStream(m_isSource); 071 072 m_lefFilter = lef; 073 } 074 075 /** 076 * Close the stream and all streams that it relies on. 077 * 078 * @exception IOException if there was an error on closing. 079 * 080 * @override Never 081 */ 082 public void close() throws IOException { 083 m_oisSource.close(); 084 m_isSource.close(); 085 086 m_oisSource = null; 087 m_isSource = null; 088 } 089 090 /** 091 * Read the next log entry that is {@link LogEntryFilter#accept accepted} by the filter from the stream. 092 * 093 * @exception IOException if an <code>IOException</code> occurred while reading from the underlying stream. 094 * Especially, this may be an <code>EOFException</code> if the end of the stream has been reached. This is 095 * the only way to find out whether there are more entries in the stream. 096 * @exception ClassNotFoundException if the exception was thrown by the underlying stream. 097 * 098 * @override Never 099 */ 100 public LogEntry readEntry() throws IOException, ClassNotFoundException { 101 102 while (true) { 103 try { 104 LogEntry le = (LogEntry)m_oisSource.readObject(); 105 106 if ((m_lefFilter == null) || (m_lefFilter.accept(le))) { 107 return le; 108 } 109 } 110 catch (StreamCorruptedException sce) { 111 m_oisSource = new ObjectInputStream(m_isSource); 112 } 113 } 114 } 115 }