1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 package net.sf.statcvs.input;
25
26 import java.io.IOException;
27 import java.io.Reader;
28 import java.util.logging.Logger;
29
30 import net.sf.statcvs.util.LookaheadReader;
31
32 /**
33 * Parses a CVS logfile. A {@link Builder} must be specified which does
34 * the construction work.
35 *
36 * @author Anja Jentzsch
37 * @author Richard Cyganiak
38 * @version $Id: CvsLogfileParser.java,v 1.17 2008/04/02 11:22:15 benoitx Exp $
39 */
40 public class CvsLogfileParser {
41
42 private static Logger logger = Logger.getLogger(CvsLogfileParser.class.getName());
43
44 private final LookaheadReader logReader;
45 private final CvsLogBuilder builder;
46
47 /**
48 * Default Constructor
49 * @param logReader a <tt>Reader</tt> containing the CVS logfile
50 * @param builder the builder that will process the log information
51 */
52 public CvsLogfileParser(final Reader logReader, final CvsLogBuilder builder) {
53 this.logReader = new LookaheadReader(logReader);
54 this.builder = builder;
55 }
56
57 /**
58 * Parses the logfile. After <tt>parse()</tt> has finished, the result
59 * of the parsing process can be obtained from the builder.
60 * @throws LogSyntaxException if syntax errors in log
61 * @throws IOException if errors while reading from the log Reader
62 */
63 public void parse() throws LogSyntaxException, IOException {
64 final long startTime = System.currentTimeMillis();
65 logger.fine("starting to parse...");
66 eatNonCheckedInFileLines();
67 if (!this.logReader.hasNextLine()) {
68 return;
69 }
70 if (!"".equals(this.logReader.getCurrentLine())) {
71 throw new LogSyntaxException("Expected '?' or empty line at line " + this.logReader.getLineNumber() + ", but found '"
72 + this.logReader.getCurrentLine() + "'");
73 }
74 eatEmptyLines();
75
76
77 boolean isFirstFile = true;
78 do {
79 final CvsFileBlockParser parser = new CvsFileBlockParser(this.logReader, this.builder, isFirstFile);
80 parser.parse();
81 isFirstFile = false;
82
83
84
85 eatEmptyLines();
86 } while (this.logReader.hasNextLine());
87
88
89
90 logger.fine("parsing finished in " + (System.currentTimeMillis() - startTime) + " ms.");
91 }
92
93 private void eatNonCheckedInFileLines() throws IOException {
94 while (this.logReader.hasNextLine() && this.logReader.nextLine().startsWith("? ")) {
95
96 }
97 }
98
99 /**
100 * Calls nextLine() on the reader until EOF or a non-empty line
101 * is found
102 */
103 private void eatEmptyLines() throws IOException {
104 while (this.logReader.hasNextLine() && "".equals(this.logReader.nextLine())) {
105
106 }
107 }
108 }