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: RepositoryFileManager.java,v $
21 Created on $Date: 2008/04/02 11:22:15 $
22 */
23 package net.sf.statcvs.input;
24
25 import java.io.BufferedReader;
26 import java.io.FileReader;
27 import java.io.IOException;
28 import java.util.Hashtable;
29 import java.util.StringTokenizer;
30 import java.util.logging.Logger;
31
32 import net.sf.statcvs.util.FileUtils;
33
34 /**
35 * Manages a checked-out repository and provides access to
36 * line number counts for repository files.
37 *
38 * @author Manuel Schulze
39 * @author Steffen Pingel
40 * @version $Id: RepositoryFileManager.java,v 1.26 2008/04/02 11:22:15 benoitx Exp $
41 */
42 public class RepositoryFileManager {
43 private static Logger logger;
44 private final String path;
45 private final Hashtable revByFilename = new Hashtable();
46
47 /**
48 * Creates a new instance with root at <code>pathName</code>.
49 *
50 * @param pathName the root of the checked out repository
51 */
52 public RepositoryFileManager(final String pathName) {
53 path = pathName;
54 logger = Logger.getLogger(getClass().getName());
55 }
56
57 /**
58 * Returns the lines of code for a repository file.
59 *
60 * @param filename a file in the repository
61 * @return the lines of code for a repository file
62 * @throws NoLineCountException when the line count could not be retrieved,
63 * for example when the file was not found.
64 */
65 public int getLinesOfCode(final String filename) throws NoLineCountException {
66 final String absoluteName = FileUtils.getAbsoluteName(this.path, filename);
67 try {
68 final FileReader freader = new FileReader(absoluteName);
69 final BufferedReader reader = new BufferedReader(freader);
70 final int linecount = getLineCount(reader);
71 logger.finer("line count for '" + absoluteName + "': " + linecount);
72 freader.close();
73 return linecount;
74 } catch (final IOException e) {
75 throw new NoLineCountException("could not get line count for '" + absoluteName + "': " + e);
76 }
77 }
78
79 private int getLineCount(final BufferedReader reader) throws IOException {
80 int linecount = 0;
81 while (reader.readLine() != null) {
82 linecount++;
83 }
84 return linecount;
85 }
86
87 /**
88 * Returns the revision of filename in the local working directory by
89 * reading the CVS/Entries file.
90 * @param filename the filename
91 * @return the revision of filename
92 */
93 public String getRevision(final String filename) throws IOException {
94 String rev = (String) revByFilename.get(filename);
95 if (rev != null) {
96 return rev;
97 }
98
99 final String baseDir = FileUtils.getParentDirectoryPath(filename);
100 final String entriesFilename = baseDir + "CVS" + FileUtils.getDefaultDirSeparator() + "Entries";
101
102 // read CVS/Entries file
103 final String absoluteName = FileUtils.getAbsoluteName(this.path, entriesFilename);
104 final BufferedReader in = new BufferedReader(new FileReader(absoluteName));
105 try {
106 String line;
107 while ((line = in.readLine()) != null) {
108 if (line.startsWith("D")) {
109 // ignore, directory entry
110 } else {
111 // cache all entries
112 final StringTokenizer t = new StringTokenizer(line, "/");
113 if (t.countTokens() >= 2) {
114 revByFilename.put(baseDir + t.nextToken(), t.nextToken());
115 } else {
116 // invalid entry
117 }
118 }
119 }
120
121 rev = (String) revByFilename.get(filename);
122 if (rev != null) {
123 return rev;
124 } else {
125 throw new IOException("File " + filename + " has no revision");
126 }
127 } finally {
128 in.close();
129 }
130 }
131
132 }