package student.weblog;
import java.io.File;
import java.util.Iterator;
import java.util.NoSuchElementException;
import java.util.Scanner;
/**
* A class to scan information from a web server access log.
* It currently supports log files from the Virginia Tech CS department's
* server proxy, which are in Apache's log format.
*
* @author Dwight Barnette (based on Stephen Edwards' {@link LogReader} class)
* @version 2003.10.31
*/
public class LogScanner
implements Iterator<LogEntry>,
Iterable<LogEntry>
{
private Scanner in;
/**
* Create a LogScanner that reads access log data from the given
* file. This constructor is provided for convenience only--it
* opens the named file and creates a scanner connected to it.
* @param file The name of the file to open
*/
public LogScanner( String file )
{
this( new File( file ) );
}
/**
* Create a LogScanner that reads access log data from the given
* file. This constructor is provided for convenience only--it
* simply creates a scanner connected to the file.
* @param file The file to open
*/
public LogScanner( File file )
{
try
{
in = new Scanner( file );
}
catch ( Exception e )
{
e.printStackTrace();
}
}
/**
* Create a LogScanner that reads access log data from the given
* stream.
* @param inStream The stream to read from
*/
public LogScanner( Scanner inStream )
{
in = inStream;
}
/**
* Does the scanner have more data to supply?
* @return true if there is more data available,
* false otherwise.
*/
public boolean hasNext()
{
return in != null && in.hasNextLine();
}
/**
* Analyze the next line from the log file and
* make it available via a LogEntry object.
*
* @return A LogEntry containing the data from the
* next log line
* @throws NoSuchElementException if there are no more log entries
* (call {@link #hasNext()} first if you want to avoid the exception)
*/
public LogEntry next()
{
if ( in == null )
{
throw new NoSuchElementException();
}
return new LogEntry( in.nextLine() );
}
/**
* Provided for compliance with the {@link Iterator} interface,
* but this method is not supported.
*
* @throws UnsupportedOperationException if you call it, since
* this operation is not supported on LogScanners
*/
public void remove()
{
throw new UnsupportedOperationException();
}
/**
* Return this object, unchanged, to provide support for foreach-style
* loops. Note that this object's log entries can only be iterated
* over once, since the collection is directly bound to the source
* lines in the {@link Scanner} (possibly attached to a file) that
* was used to create this LogScanner.
*
* @return this object, unchanged (since it already implements
* Iterator<LogEntry>)
*/
public Iterator<LogEntry> iterator()
{
return this;
}
/**
* A synonym for {@link #hasNext()} provided for backward
* compatibility with the older Java 1.4-style {@link LogReader}
* class.
* @return true if there is more data available,
* false otherwise.
*/
public boolean hasMoreEntries()
{
return hasNext();
}
/**
* A synonym for {@link #hasNext()} provided for backward
* compatibility with the older Java 1.4-style {@link LogReader}
* class. This one silently converts NoSuchElementExceptions
* into null return values for backward compatibility.
*
* @return A LogEntry containing the data from the
* next log line, or null if there are no more lines.
*/
public LogEntry nextEntry()
{
LogEntry result = null;
try
{
result = next();
}
catch ( NoSuchElementException e )
{
// ignore this error and silently return null
}
return result;
}
}