/* Copyright (c) 2008-2010, developers of the Ascension Log Visualizer
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom
* the Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
package com.googlecode.logVisualizer.parser;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.googlecode.logVisualizer.logData.LogDataHolder;
/**
* A basic implementation of the {@link LogParser} interface for an ascension
* log parser. The needed back end data structures and generic helper-methods
* for parsing are implemented.
* <p>
* All methods in this class throw a {@link NullPointerException} if a null
* object reference is passed in any parameter.
*/
public abstract class AbstractLogParser implements LogParser {
private final LogDataHolder logData;
private final List<LineParser> lineParsers = new ArrayList<>();
private final List<BlockParser> blockParsers = new ArrayList<>();
/**
* @param logData
* The log data of this log parser to set.
*/
public AbstractLogParser(final LogDataHolder logData) {
if (logData == null) {
throw new NullPointerException(
"The LogDataHolder must not be null.");
}
this.logData = logData;
}
/**
* This method tries to parse the given line with one of the line parsers it
* has.
* <p>
* This should always be the method of choice to parse lines in actual
* implementations of this class.
* <p>
* This implementation iterates over the internal line parser list and lets
* all line parsers try to parse data out of the given line. If one of the
* line parsers was able to parse the line, the loop is ended without
* checking another parser. Thus the line parser list shouldn't contain
* parsers which are able to parse the same line.
*
* @param line
* The line to be parsed.
*/
protected void parseLine(final String line) {
for (final LineParser lp : this.lineParsers) {
// If the parser can parse the line, this method also returns true.
// This is used to cut back on the amount of loops.
if (lp.parseLine(line, this.logData)) {
break;
}
}
}
/**
* This method tries to parse multiple lines from the given log reader with
* one of the block parsers it has.
* <p>
* This should always be the method of choice to parse blocks in actual
* implementations of this class.
* <p>
* This implementation saves the next line returned by the BufferedReader
* and checks it with ever block parser to see whether one of them
* recognises it as the first line of parsable block. Thus, this method will
* not catch different parsable blocks that directly follow each other in
* one runthrough. Developers have to plan for such cases accordingly by
* making sure that block parsers leave the BufferedReader in a position
* that makes it possible for another block parser to recognise a compatible
* block in a following call of this method.
*
* @param reader
* The line to be parsed.
*/
protected void parseBlock(final BufferedReader reader) throws IOException {
if (!this.blockParsers.isEmpty()) {
// Get the next line and reset the reader back to its previous
// position afterwards.
// A 500 characters limit should be enough for this (maybe too
// much).
reader.mark(500);
final String line = reader.readLine();
reader.reset();
if ((line != null) && (line.length() > 0)) {
for (final BlockParser bp : this.blockParsers) {
bp.parseBlock(line, reader, this.logData);
}
}
}
}
/**
* @return The log data of this log parser.
*/
@Override
public LogDataHolder getLogData() {
return this.logData;
}
/**
* @param lineParser
* The line parser to add.
*/
protected void addLineParser(final LineParser lineParser) {
this.lineParsers.add(lineParser);
}
/**
* @param blockParser
* The block parser to add.
*/
protected void addBlockParser(final BlockParser blockParser) {
this.blockParsers.add(blockParser);
}
}