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: 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 }