1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 }