View Javadoc

1   package net.sf.statsvn.util.svnkit;
2   
3   import java.io.ByteArrayInputStream;
4   import java.io.ByteArrayOutputStream;
5   import java.io.File;
6   import java.io.IOException;
7   import java.util.Vector;
8   
9   import net.sf.statsvn.output.SvnConfigurationOptions;
10  import net.sf.statsvn.util.BinaryDiffException;
11  import net.sf.statsvn.util.StringUtils;
12  import net.sf.statsvn.util.SvnDiffUtils;
13  
14  import org.tmatesoft.svn.core.SVNDepth;
15  import org.tmatesoft.svn.core.SVNException;
16  import org.tmatesoft.svn.core.wc.SVNClientManager;
17  import org.tmatesoft.svn.core.wc.SVNRevision;
18  
19  /**
20   *
21   * Performs diffs via svnkit. 
22   * 
23   * @author jkealey, yogesh
24   *
25   */
26  public class SvnKitDiff extends SvnDiffUtils {
27  
28      /**
29       * This method converts absolute paths inside the diff output to relative ones. 
30       */
31      private static String replaceRelativePathWithinDiffData(File rootDirectory, String diffData) {
32          String rootPath = rootDirectory.getAbsoluteFile().getAbsolutePath();
33          //        rootPath =  rootPath.replace(File.separator, "/") + "/"; // removing dependency to jdk1.5
34          rootPath = StringUtils.replace(File.separator, "/", rootPath);
35          // return diffData.replace(rootPath, "");  // removing dependency to jdk1.5
36          return StringUtils.replace(rootPath, "", diffData);
37      }
38  
39      /**
40       * Performs diffs via svnkit. 
41       * 
42       * @param processor the base processor  
43       */
44      public SvnKitDiff(SvnKitProcessor processor) {
45          super(processor);
46      }
47  
48      /**
49       * Shorthand to get the checked out directory
50       * @return the checked out directory 
51       */
52      public File getCheckoutDirectory() {
53          return getSvnKitProcessor().getCheckoutDirectory();
54      }
55  
56      /**
57       * Gets diffs inside one revision. 
58       * 
59       * @return a list of diffs that were extracted from one particular revision    
60       */
61      public Vector getLineDiff(String newRevNr) throws IOException, BinaryDiffException {
62          ByteArrayOutputStream diffBytes = new ByteArrayOutputStream();
63          int revisionNo = Integer.parseInt(newRevNr);
64          try {
65              getManager().getDiffClient().doDiff(getCheckoutDirectory(), SVNRevision.create(revisionNo), SVNRevision.create(revisionNo - 1),
66                      SVNRevision.create(revisionNo), SVNDepth.INFINITY, false, diffBytes, null);
67          } catch (SVNException ex) {
68              handleSvnException(ex);
69          }
70          String modDiffDataStr = replaceRelativePathWithinDiffData(getCheckoutDirectory(), diffBytes.toString());
71  
72          final Vector answer = new Vector();
73          parseMultipleDiffStream(answer, new ByteArrayInputStream(modDiffDataStr.getBytes()));
74          return answer;
75      }
76  
77      /**
78       * Gets a single diff for a file between two revisions. 
79       */
80      public int[] getLineDiff(String oldRevNr, String newRevNr, String filename) throws IOException, BinaryDiffException {
81  
82          int oldRevisionNo = Integer.parseInt(oldRevNr);
83          int newRevisionNo = Integer.parseInt(newRevNr);
84          File newFile = new File(getProcessor().getInfoProcessor().relativeToAbsolutePath(filename));
85          File oldFile = newFile;
86          ByteArrayOutputStream diffBytes = new ByteArrayOutputStream();
87          try {
88              getManager().getDiffClient().doDiff(oldFile, SVNRevision.create(oldRevisionNo), newFile, SVNRevision.create(newRevisionNo), SVNDepth.INFINITY,
89                      false, diffBytes, null);
90          } catch (SVNException ex) {
91              handleSvnException(ex);
92          }
93          String modDiffDataStr = replaceRelativePathWithinDiffData(getCheckoutDirectory(), diffBytes.toString());
94  
95          return parseSingleDiffStream(new ByteArrayInputStream(modDiffDataStr.getBytes()));
96      }
97  
98      /**
99       * Shorthand for the svnkit client manager. 
100      * 
101      * @return the svnkit client manager
102      */
103     public SVNClientManager getManager() {
104         return getSvnKitProcessor().getManager();
105     }
106 
107     /**
108      * Shorthand to get the base processor 
109      * @return the base processor 
110      */
111     public SvnKitProcessor getSvnKitProcessor() {
112         return (SvnKitProcessor) getProcessor();
113     }
114 
115     /**
116      * Logs svn exceptions and transforms them into IOExceptions to fit in the existing framework 
117      * 
118      * @param ex the exception 
119      * @throws IOException a re-thrown exception 
120      */
121     private void handleSvnException(SVNException ex) throws IOException {
122         String msg = "svn diff " + ex.getMessage();
123         SvnConfigurationOptions.getTaskLogger().error(msg);
124         throw new IOException(msg);
125     }
126 }