View Javadoc

1   package net.sf.statsvn.util;
2   
3   import java.io.FileInputStream;
4   import java.io.IOException;
5   import java.io.InputStream;
6   import java.io.InputStreamReader;
7   import java.util.ArrayList;
8   import java.util.List;
9   
10  import net.sf.statcvs.util.LookaheadReader;
11  import net.sf.statsvn.output.SvnConfigurationOptions;
12  
13  /**
14   * Utilities class that manages calls to svn propget. Used to find binary files.
15   * 
16   * @author Jason Kealey <jkealey@shade.ca>
17   * 
18   * @version $Id: SvnPropgetUtils.java 394 2009-08-10 20:08:46Z jkealey $
19   */
20  public  class SvnPropgetUtils implements ISvnPropgetProcessor {
21  
22  	protected List binaryFiles;
23  
24      protected ISvnProcessor processor;
25  
26      /**
27       * Invokes propget via the svn propget via the command line.  
28       */
29      public SvnPropgetUtils(ISvnProcessor processor) {
30          this.processor = processor;
31      }
32  
33      protected ISvnProcessor getProcessor() {
34          return processor;
35      }
36  
37  	/**
38  	 * Get the svn:mime-types for all files, latest revision.
39  	 * 
40  	 * @return the inputstream from which to read the information.
41  	 */
42  	protected synchronized ProcessUtils getFileMimeTypes() {
43  		return getFileMimeTypes(null, null);
44  	}
45  
46  	/**
47  	 * Get the svn:mime-type for a certain file (leave null for all files).
48  	 * 
49  	 * @param revision
50  	 *            revision for which to query;
51  	 * @param filename
52  	 *            the filename (or null for all files)
53  	 * @return the inputstream from which to read the information.
54  	 */
55  	protected synchronized ProcessUtils getFileMimeTypes(final String revision, final String filename) {
56  		String svnPropgetCommand = "svn propget svn:mime-type";
57  		if (revision != null && revision.length() > 0) {
58  			svnPropgetCommand += " -r " + revision;
59  		}
60  
61  		if (filename != null && filename.length() > 0) {
62  			svnPropgetCommand += " " + StringUtils.replace(" ", "%20", getProcessor().getInfoProcessor().relativePathToUrl(filename));
63  
64  			if (revision != null && revision.length() > 0) {
65  				svnPropgetCommand += "@" + revision;
66  			}
67  		} else {
68  			svnPropgetCommand += " -R ";
69  		}
70  
71  		svnPropgetCommand += SvnCommandHelper.getAuthString();
72  
73  		try {
74  			return ProcessUtils.call(svnPropgetCommand);
75  		} catch (final Exception e) {
76  			SvnConfigurationOptions.getTaskLogger().info(e.toString());
77  			return null;
78  		}
79  	}
80  
81  	/* (non-Javadoc)
82       * @see net.sf.statsvn.util.ISvnPropgetProcessor#getBinaryFiles()
83       */
84  	public List getBinaryFiles() {
85  		if (binaryFiles == null) {
86  			ProcessUtils pUtils = null;
87  			try {
88  				pUtils = getFileMimeTypes();
89  				loadBinaryFiles(pUtils);
90  			} finally {
91  				if (pUtils != null) {
92  					try {
93  						pUtils.close();
94  					} catch (final IOException e) {
95  						SvnConfigurationOptions.getTaskLogger().info(e.toString());
96  					}
97  				}
98  			}
99  		}
100 
101 		return binaryFiles;
102 	}
103 	
104 	
105     /**
106      * Loads the list of binary files from the input stream equivalent to an svn
107      * propget command.
108      * 
109      * @param path
110      *            a file on disk which contains the results of an svn propget
111      */	
112 	public void loadBinaryFiles(final String path) throws IOException
113 	{
114        final InputStream stream = new FileInputStream(path);
115         final ProcessUtils pUtils = new ProcessUtils();
116         try {
117             pUtils.setInputStream(stream);
118             loadBinaryFiles(pUtils);
119         } finally {
120             pUtils.close();
121         }
122 	}
123 	/**
124 	 * Loads the list of binary files from the input stream equivalent to an svn
125 	 * propget command.
126 	 * 
127 	 * @param stream
128 	 *            stream equivalent to an svn propget command
129 	 */
130 	protected void loadBinaryFiles(final ProcessUtils pUtils) {
131 		binaryFiles = new ArrayList();
132 		final LookaheadReader mimeReader = new LookaheadReader(new InputStreamReader(pUtils.getInputStream()));
133 		try {
134 			while (mimeReader.hasNextLine()) {
135 				mimeReader.nextLine();
136 				final String file = getBinaryFilename(mimeReader.getCurrentLine(), false);
137 				if (file != null) {
138 					binaryFiles.add(file);
139 				}
140 			}
141 			if (pUtils.hasErrorOccured()) {
142 				throw new IOException(pUtils.getErrorMessage());
143 			}
144 		} catch (final IOException e) {
145 			SvnConfigurationOptions.getTaskLogger().info(e.getMessage());
146 		}
147 	}
148 
149 	/* (non-Javadoc)
150      * @see net.sf.statsvn.util.ISvnPropgetProcessor#isBinaryFile(java.lang.String, java.lang.String)
151      */
152 	public boolean isBinaryFile(final String revision, final String filename) {
153 		ProcessUtils pUtils = null;
154 		try {
155 			pUtils = getFileMimeTypes(revision, filename);
156 			final LookaheadReader mimeReader = new LookaheadReader(new InputStreamReader(pUtils.getInputStream()));
157 			while (mimeReader.hasNextLine()) {
158 				mimeReader.nextLine();
159 				final String file = getBinaryFilename(mimeReader.getCurrentLine(), true);
160 				if (file != null && file.equals(filename)) {
161 					return true;
162 				}
163 			}
164 		} catch (final IOException e) {
165 			SvnConfigurationOptions.getTaskLogger().info(e.toString());
166 		} finally {
167 			if (pUtils != null) {
168 				try {
169 					pUtils.close();
170 				} catch (final IOException e) {
171 					SvnConfigurationOptions.getTaskLogger().info(e.toString());
172 				}
173 			}
174 		}
175 
176 		return false;
177 	}
178 
179 	/**
180 	 * Given a string such as: "lib\junit.jar - application/octet-stream" or
181 	 * "svn:\\host\repo\lib\junit.jar - application/octet-stream" will return
182 	 * the filename if the mime type is binary (doesn't end with text/*)
183 	 * 
184 	 * Will return the filename with / was a directory seperator.
185 	 * 
186 	 * @param currentLine
187 	 *            the line obtained from svn propget svn:mime-type
188 	 * @param removeRoot
189 	 *            if true, will remove any repository prefix
190 	 * @return should return lib\junit.jar in both cases, given that
191 	 *         removeRoot==true in the second case.
192 	 */
193 	protected String getBinaryFilename(final String currentLine, final boolean removeRoot) {
194 		// want to make sure we only have / in end result.
195 		String line = removeRoot ? currentLine : currentLine.replace('\\', '/');
196 
197 		// HACK: See bug 18. if removeRoot==true, no - will be found because we
198 		// are calling for one specific file.
199 		final String octetStream = " - application/octet-stream";
200 		// if is common binary file or identified as something other than text
201 		if (line.endsWith(octetStream) || line.lastIndexOf(" - text/") < 0 && line.lastIndexOf(" - text/") == line.lastIndexOf(" - ")
202 		        && line.lastIndexOf(" - ") >= 0) {
203 			line = line.substring(0, line.lastIndexOf(" - "));
204 			if (removeRoot) {
205 				line = getProcessor().getInfoProcessor().urlToRelativePath(line);
206 			}
207 			return line;
208 		}
209 
210 		return null;
211 	}
212 
213 }