001    package org.hackystat.sensor.ant.vcs;
002    
003    import org.apache.commons.jrcs.diff.Chunk;
004    import org.apache.commons.jrcs.diff.Delta;
005    import org.apache.commons.jrcs.diff.Diff;
006    import org.apache.commons.jrcs.diff.Revision;
007    
008    
009    /**
010     * Diff counter, which wraps around JRCS diff engine. <p>
011     * Note that if this class is used to diff two text files, then empty lines and
012     * comments are considered in diff result. This may or may not be desired.
013     * Also note that if you try to diff two binary files, you either get an exception or
014     * an incorrect result.
015     * 
016     * @author Qin ZHANG
017     * @version $Id: GenericDiffCounter.java,v 1.1.1.1 2005/10/20 23:56:56 johnson Exp $
018     */
019    public class GenericDiffCounter {
020    
021      private int linesAdded = 0;
022      private int linesDeleted = 0;
023      
024      /**
025       * Constructs this instance to diff two revisions.
026       *
027       * @param original The original version.
028       * @param revised The revision.
029       * @throws Exception If there is error in diff engine.
030       */
031      public GenericDiffCounter(Object[] original, Object[] revised) throws Exception {
032        Diff dfEngine = new Diff(original);
033        Revision revision = dfEngine.diff(revised);
034    
035        for (int i = 0; i < revision.size(); i++) {
036          Delta delta = revision.getDelta(i);
037          Chunk fromChunk = delta.getOriginal();
038          Chunk toChunk = delta.getRevised();
039          this.linesDeleted += fromChunk.size();
040          this.linesAdded += toChunk.size();
041        }
042    
043        //Following is redundant, it only serves to check whether diff is correct.
044        //Since the version of JRCS used is not final, double-checking is always good.
045        Object[] reco = revision.patch(original);
046        if (!Diff.compare(revised, reco)) {
047          throw new Exception("JRCS Diff internal error: files differ after patching.");
048        }
049        //END OF redundant code
050      }
051    
052      /**
053       * Gets the lines added.
054       *
055       * @return The number of lines added.
056       */
057      public int getLinesAdded() {
058        return this.linesAdded;
059      }
060    
061      /**
062       * Gets the lines deleted.
063       *
064       * @return The number of lines deleted.
065       */
066      public int getLinesDeleted() {
067        return this.linesDeleted;
068      }
069    }