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 }