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: 2004/12/14 13:38:13 $
22 */
23 package net.sf.statsvn.input;
24
25 import java.io.BufferedReader;
26 import java.io.FileReader;
27 import java.io.IOException;
28 import java.util.Vector;
29
30 import net.sf.statcvs.input.LogSyntaxException;
31 import net.sf.statcvs.input.NoLineCountException;
32 import net.sf.statcvs.util.FileUtils;
33 import net.sf.statsvn.output.SvnConfigurationOptions;
34 import net.sf.statsvn.util.BinaryDiffException;
35 import net.sf.statsvn.util.SvnDiffUtils;
36 import net.sf.statsvn.util.SvnInfoUtils;
37 import net.sf.statsvn.util.SvnPropgetUtils;
38
39 /**
40 * Manages a checked-out repository and provides access to line number counts
41 * for repository files.
42 *
43 * New in StatSVN: Also provides a central point of access to abstract out calls
44 * to the server. Many of the methods here simply redirect to the static
45 * util/SvnXXXUtils classes. Therefore, clients don't have to know where the
46 * information is located, they can simply invoke this class.
47 *
48 * @author Manuel Schulze
49 * @author Steffen Pingel
50 * @author Jason Kealey <jkealey@shade.ca>
51 *
52 * @version $Id: RepositoryFileManager.java 351 2008-03-28 18:46:26Z benoitx $
53 */
54 public class RepositoryFileManager {
55 private final String path;
56
57 /**
58 * Creates a new instance with root at <code>pathName</code>.
59 *
60 * @param pathName
61 * the root of the checked out repository
62 */
63 public RepositoryFileManager(final String pathName) {
64 path = pathName;
65 }
66
67 /**
68 * Converts an absolute path in the repository to a URL, using the
69 * repository URL
70 *
71 * @param absolute
72 * Example: /trunk/statsvn/package.html
73 * @return Example: svn://svn.statsvn.org/statsvn/trunk/statsvn/package.html
74 */
75 public String absolutePathToUrl(final String absolute) {
76 return SvnInfoUtils.absolutePathToUrl(absolute);
77 }
78
79 /**
80 * Converts an absolute path in the repository to a path relative to the
81 * working folder root.
82 *
83 * Will return null if absolute path does not start with getModuleName();
84 *
85 * @param absolute
86 * Example (assume getModuleName() returns /trunk/statsvn)
87 * /trunk/statsvn/package.html
88 * @return Example: package.html
89 */
90 public String absoluteToRelativePath(final String stringData) {
91 return SvnInfoUtils.absoluteToRelativePath(stringData);
92 }
93
94 /**
95 * Adds a directory to the list of known directories. Used when inferring
96 * implicit actions on deleted paths.
97 *
98 * @param relativePath
99 * the relative path.
100 */
101 public void addDirectory(final String relativePath) {
102 SvnInfoUtils.addDirectory(relativePath);
103 }
104
105 /**
106 * Returns true if the file exists in the working copy (according to the svn
107 * metadata, and not file system checks).
108 *
109 * @param relativePath
110 * the path
111 * @return <tt>true</tt> if it exists
112 */
113 public boolean existsInWorkingCopy(final String relativePath) {
114 return SvnInfoUtils.existsInWorkingCopy(relativePath);
115 }
116
117 /**
118 * Counts lines on a BufferedReader
119 *
120 * @param reader
121 * the buffered reader
122 * @return the number of lines read
123 * @throws IOException
124 * error reading from reader
125 */
126 protected int getLineCount(final BufferedReader reader) throws IOException {
127 int linecount = 0;
128 while (reader.readLine() != null) {
129 linecount++;
130 }
131 return linecount;
132 }
133
134 /**
135 * Returns line count differences between two revisions of a file.
136 *
137 * @param oldRevNr
138 * old revision number
139 * @param newRevNr
140 * new revision number
141 * @param filename
142 * the filename
143 * @return A int[2] array of [lines added, lines removed] is returned.
144 * @throws IOException
145 * problem parsing the stream
146 * @throws BinaryDiffException
147 * if the error message is due to trying to diff binary files.
148 *
149 */
150 public int[] getLineDiff(final String oldRevNr, final String newRevNr, final String filename) throws IOException, BinaryDiffException {
151 return SvnDiffUtils.getLineDiff(oldRevNr, newRevNr, filename);
152 }
153
154 /**
155 * Returns line count differences for all files in a particular revision.
156 *
157 * @param newRevNr
158 * new revision number
159 * @return A vector of object[3] array of [filename, int[2](lines added, lines removed), isBinary] is returned.
160 * @throws IOException
161 * problem parsing the stream
162 * @throws BinaryDiffException
163 * if the error message is due to trying to diff binary files.
164 */
165 public Vector getRevisionDiff(final String newRevNr) throws IOException, BinaryDiffException {
166 return SvnDiffUtils.getLineDiff(newRevNr);
167 }
168
169 /**
170 * Returns the lines of code for a repository file. (Currently checked out
171 * version)
172 *
173 * @param filename
174 * a file in the repository
175 * @return the lines of code for a repository file
176 * @throws NoLineCountException
177 * when the line count could not be retrieved, for example when
178 * the file was not found.
179 */
180 public int getLinesOfCode(final String filename) throws NoLineCountException {
181 final String absoluteName = FileUtils.getAbsoluteName(this.path, filename);
182 try {
183 final FileReader freader = new FileReader(absoluteName);
184 final BufferedReader reader = new BufferedReader(freader);
185 final int linecount = getLineCount(reader);
186 SvnConfigurationOptions.getTaskLogger().log("line count for '" + absoluteName + "': " + linecount);
187 freader.close();
188 return linecount;
189 } catch (final IOException e) {
190 throw new NoLineCountException("could not get line count for '" + absoluteName + "': " + e);
191 }
192 }
193
194 /**
195 * Assumes #loadInfo(String) has been called. Never ends with /, might be
196 * empty.
197 *
198 * @return The absolute path of the root of the working folder in the
199 * repository.
200 */
201 public String getModuleName() {
202 return SvnInfoUtils.getModuleName();
203 }
204
205 /**
206 * Assumes #loadInfo(String) has been called.
207 *
208 * @return The uuid of the repository.
209 */
210 public String getRepositoryUuid() {
211 return SvnInfoUtils.getRepositoryUuid();
212 }
213
214 /**
215 * Returns the revision of filename in the local working directory by
216 * reading the svn metadata.
217 *
218 * @param filename
219 * the filename
220 * @return the revision of filename
221 */
222 public String getRevision(final String filename) throws IOException {
223 final String rev = SvnInfoUtils.getRevisionNumber(filename);
224 if (rev != null) {
225 return rev;
226 } else if (SvnInfoUtils.isDirectory(filename)) {
227 return null;
228 } else {
229 throw new IOException("File " + filename + " has no revision");
230 }
231 }
232
233 /**
234 * Assumes #loadInfo(String) has been called.
235 *
236 * @return the revision number of the root of the working folder
237 * (last checked out revision number)
238 */
239 public String getRootRevisionNumber() {
240 return SvnInfoUtils.getRootRevisionNumber();
241 }
242
243 /**
244 * Is the given path a binary file in the <b>working</b> directory?
245 *
246 * @param relativePath
247 * the directory
248 * @return true if it is marked as a binary file
249 */
250 public boolean isBinary(final String relativePath) {
251 return SvnPropgetUtils.getBinaryFiles().contains(relativePath);
252 }
253
254 /**
255 * Returns true if the path has been identified as a directory.
256 *
257 * @param relativePath
258 * the path
259 * @return true if it is a known directory.
260 */
261 public boolean isDirectory(final String relativePath) {
262 return SvnInfoUtils.isDirectory(relativePath);
263 }
264
265 /**
266 * Initializes our representation of the repository.
267 *
268 * @throws LogSyntaxException
269 * if the svn info --xml is malformed
270 * @throws IOException
271 * if there is an error reading from the stream
272 */
273 public void loadInfo() throws LogSyntaxException, IOException {
274 SvnInfoUtils.loadInfo();
275 }
276
277 /**
278 * Converts a relative path in the working folder to a URL, using the
279 * working folder's root URL
280 *
281 * @param relative
282 * Example: src/Messages.java
283 * @return Example:
284 * svn://svn.statsvn.org/statsvn/trunk/statsvn/src/Messages.java
285 *
286 */
287 public String relativePathToUrl(final String relative) {
288 return SvnInfoUtils.relativePathToUrl(relative);
289 }
290
291 /**
292 * Converts a relative path in the working folder to an absolute path in the
293 * repository.
294 *
295 * @param relative
296 * Example: src/Messages.java
297 * @return Example: /trunk/statsvn/src/Messages.java
298 *
299 */
300 public String relativeToAbsolutePath(final String relative) {
301 return SvnInfoUtils.relativeToAbsolutePath(relative);
302 }
303
304 /**
305 * Converts a url to an absolute path in the repository.
306 *
307 * @param url
308 * Examples: svn://svn.statsvn.org/statsvn/trunk/statsvn,
309 * svn://svn.statsvn.org/statsvn/trunk/statsvn/package.html
310 * @return Example: /trunk/statsvn, /trunk/statsvn/package.html
311 */
312 public String urlToAbsolutePath(final String url) {
313 return SvnInfoUtils.urlToAbsolutePath(url);
314 }
315
316 /**
317 * Converts a url to a relative path in the repository.
318 *
319 * @param url
320 * Examples: svn://svn.statsvn.org/statsvn/trunk/statsvn,
321 * svn://svn.statsvn.org/statsvn/trunk/statsvn/package.html
322 * @return Example: ".", package.html
323 */
324 public String urlToRelativePath(final String url) {
325 return SvnInfoUtils.urlToRelativePath(url);
326 }
327 }