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