View Javadoc

1   /*
2       StatCvs - CVS statistics generation 
3       Copyright (C) 2002  Lukasz Pekacki <lukasz@pekacki.de>
4       http://statcvs.sf.net/
5       
6       This library is free software; you can redistribute it and/or
7       modify it under the terms of the GNU Lesser General Public
8       License as published by the Free Software Foundation; either
9       version 2.1 of the License, or (at your option) any later version.
10  
11      This library is distributed in the hope that it will be useful,
12      but WITHOUT ANY WARRANTY; without even the implied warranty of
13      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14      Lesser General Public License for more details.
15  
16      You should have received a copy of the GNU Lesser General Public
17      License along with this library; if not, write to the Free Software
18      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19      
20  	$RCSfile: CvsLogfileParser.java,v $ 
21  	Created on $Date: 2008/04/02 11:22:15 $ 
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          //		TODO: uncomment when tag/branch reports are added 
76          //		boolean isLogWithoutSymbolicNames = false;
77          boolean isFirstFile = true;
78          do {
79              final CvsFileBlockParser parser = new CvsFileBlockParser(this.logReader, this.builder, isFirstFile);
80              parser.parse();
81              isFirstFile = false;
82              //			if (parser.isLogWithoutSymbolicNames()) {
83              //				isLogWithoutSymbolicNames = true;
84              //			}
85              eatEmptyLines();
86          } while (this.logReader.hasNextLine());
87          //		if (isLogWithoutSymbolicNames) {
88          //			logger.warning("Log was created with '-N' switch of 'cvs log', some reports will be missing!");
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              // ignore lines starting with "? "
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             // ignore empty lines
106         }
107     }
108 }