Coverage Report - net.sf.statcvs.model.Revision
 
Classes in this File Line Coverage Branch Coverage Complexity
Revision
0%
0/106
0%
0/78
2.345
 
 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: Revision.java,v $ 
 21  
         Created on $Date: 2009/08/20 17:44:05 $ 
 22  
 */
 23  
 package net.sf.statcvs.model;
 24  
 
 25  
 import java.util.Date;
 26  
 import java.util.Iterator;
 27  
 import java.util.SortedSet;
 28  
 
 29  
 /**
 30  
  * One revision of a {@link VersionedFile}. That can be an initial revision
 31  
  * (checkin), a change, a deletion, or a re-add. Revisions are created
 32  
  * using the methods {@link VersionedFile#addInitialRevision},
 33  
  * {@link VersionedFile#addChangeRevision} and
 34  
  * {@link VersionedFile#addDeletionRevision}.
 35  
  *
 36  
  * TODO: Replace type code with hierarchy
 37  
  * TODO: Rename class to Revision, getAuthor() to getLogin(), isDead() to isDeletion()
 38  
  * 
 39  
  * @author Manuel Schulze
 40  
  * @author Richard Cyganiak <richard@cyganiak.de>
 41  
  * @version $Id: Revision.java,v 1.3 2009/08/20 17:44:05 benoitx Exp $
 42  
  */
 43  
 public class Revision implements Comparable {
 44  
 
 45  
     /**
 46  
      * Marks a revision that creates a new file. The file did not exist
 47  
      * in the current branch before this revision, and it does exist
 48  
      * afterwards. Possibly the file existed before, that is, it was
 49  
      * deleted and restored. 
 50  
      */
 51  
     public static final int TYPE_CREATION = 1;
 52  
 
 53  
     /**
 54  
      * Marks a revision that changes the file. It does neither create nor
 55  
      * delete the file.
 56  
      */
 57  
     public static final int TYPE_CHANGE = 2;
 58  
 
 59  
     /**
 60  
      * Marks a revision that deletes the file. The file existed before, but
 61  
      * does not exist afterwards in the current branch.
 62  
      */
 63  
     public static final int TYPE_DELETION = 3;
 64  
 
 65  
     /**
 66  
      * Marks a revision at the very beginning of the log timespan. This is
 67  
      * only a container for the number of code lines at the beginning of
 68  
      * the log. It is not a real revision committed by an author.
 69  
      */
 70  
     public static final int TYPE_BEGIN_OF_LOG = 5;
 71  
 
 72  
     private final VersionedFile file;
 73  
     private final String revisionNumber;
 74  
     private final int type;
 75  
     private final Author author;
 76  
     private final Date date;
 77  
     private final String comment;
 78  
     private final int lines;
 79  
     private final int linesReplaced;
 80  
     private final int linesDelta;
 81  
 
 82  
     private final SortedSet symbolicNames;
 83  
 
 84  
     /**
 85  
      * Creates a new revision of a file with the
 86  
      * specified revision number. Should not be called directly. Instead,
 87  
      * {@link VersionedFile#addInitialRevision} and its sister methods should
 88  
      * be used.
 89  
      * @param file VersionedFile that belongs to this revision
 90  
      * @param revisionNumber revision number, for example "1.1"
 91  
      * @param type a <tt>TYPE_XXX</tt> constant
 92  
      * @param author the author of the revision
 93  
      * @param date the date of the revision
 94  
      * @param comment the author's comment
 95  
      * @param lines number of lines; 0 for deletions
 96  
      * @param linesDelta by how much did the number of lines change, compared to the previous revision?
 97  
      * @param linesReplaced How many lines were removed and replaced by other lines, without the delta changing?
 98  
      * @param symbolicNames list of symbolic names for this revision or null if this revision has no symbolic names         
 99  
      */
 100  
     public Revision(final VersionedFile file, final String revisionNumber, final int type, final Author author, final Date date, final String comment,
 101  0
             final int lines, final int linesDelta, final int linesReplaced, final SortedSet symbolicNames) {
 102  0
         this.file = file;
 103  0
         this.revisionNumber = revisionNumber;
 104  0
         this.type = type;
 105  0
         this.author = author;
 106  0
         this.date = date;
 107  0
         this.comment = comment;
 108  0
         this.lines = lines;
 109  0
         this.linesDelta = linesDelta;
 110  0
         this.linesReplaced = linesReplaced;
 111  0
         this.symbolicNames = symbolicNames;
 112  
 
 113  0
         if (author != null) {
 114  0
             author.addRevision(this);
 115  
         }
 116  
 
 117  0
         if (symbolicNames != null) {
 118  0
             final Iterator it = symbolicNames.iterator();
 119  0
             while (it.hasNext()) {
 120  0
                 ((SymbolicName) it.next()).addRevision(this);
 121  
             }
 122  
         }
 123  0
     }
 124  
 
 125  
     /**
 126  
      * Returns the revision number.
 127  
      * @return the revision number
 128  
      */
 129  
     public String getRevisionNumber() {
 130  0
         return revisionNumber;
 131  
     }
 132  
 
 133  
     /**
 134  
      * Returns the author of this revision.
 135  
      * @return the author
 136  
      */
 137  
     public Author getAuthor() {
 138  0
         return author;
 139  
     }
 140  
 
 141  
     /**
 142  
      * Returns the comment for this revision.
 143  
      * @return the comment
 144  
      */
 145  
     public String getComment() {
 146  0
         return comment;
 147  
     }
 148  
 
 149  
     /**
 150  
      * Returns the date of this revision.
 151  
      * @return the date
 152  
      */
 153  
     public Date getDate() {
 154  0
         return date;
 155  
     }
 156  
 
 157  
     /**
 158  
      * Returns the number of lines for this revision. This is 0 for
 159  
      * dead revisions.
 160  
      * 
 161  
      * @return the number of lines
 162  
      */
 163  
     public int getLines() {
 164  0
         return lines;
 165  
     }
 166  
 
 167  
     /**
 168  
      * Returns by how many lines the line count changed with this
 169  
      * revision. Deletions return <code>-getLines()</code>,
 170  
      * re-adds and initial revisions return <code>getLines()</code>.
 171  
      * 
 172  
      * @return the line count change of this revision
 173  
      */
 174  
     public int getLinesDelta() {
 175  0
         return linesDelta;
 176  
     }
 177  
 
 178  
     /**
 179  
      * Returns the number of lines that were removed and replaced
 180  
      * by other lines in this revision. For example, if 5 lines were
 181  
      * added and 2 lines removed, this would be 3. If 1 line was added
 182  
      * and 1 was removed, it would be 1. If it was an initial revision
 183  
      * or a deletion, it would be 0.
 184  
      * 
 185  
      * @return the number of lines that were replaced by other lines.
 186  
      */
 187  
     public int getReplacedLines() {
 188  0
         return linesReplaced;
 189  
     }
 190  
 
 191  
     /**
 192  
      * Returns the number of "new" lines in this revision. This is the
 193  
      * sum of added and changed lines. In other words, all the "original"
 194  
      * lines the author of this revision came up with.
 195  
      * @return lines changed or added
 196  
      */
 197  
     public int getNewLines() {
 198  0
         if (getLinesDelta() > 0) {
 199  0
             return getLinesDelta() + getReplacedLines();
 200  
         }
 201  0
         return getReplacedLines();
 202  
     }
 203  
 
 204  
     /**
 205  
      * Returns the change of the file count caused by this revision.
 206  
      * This is 1 for initial revisions and re-adds, -1 for deletions,
 207  
      * and 0 for normal revisions.
 208  
      * @return the file count change of this revision
 209  
      */
 210  
     public int getFileCountDelta() {
 211  0
         if (isInitialRevision()) {
 212  0
             return 1;
 213  0
         } else if (isDead()) {
 214  0
             return -1;
 215  
         } else {
 216  0
             return 0;
 217  
         }
 218  
     }
 219  
 
 220  
     /**
 221  
      * Returns <code>true</code> if the file did not exist before this
 222  
      * revision and does exist afterwards. Possibly the file was deleted
 223  
      * before, or it never existed before.
 224  
      * 
 225  
      * @return <code>true</code> if the file did not exist before
 226  
      */
 227  
     public boolean isInitialRevision() {
 228  0
         return type == TYPE_CREATION;
 229  
     }
 230  
 
 231  
     /**
 232  
      * Returns <tt>true</tt> if the file is deleted in this revision.
 233  
      * @return <code>true</code> if the file is deleted in this revision
 234  
      */
 235  
     public boolean isDead() {
 236  0
         return type == TYPE_DELETION;
 237  
     }
 238  
 
 239  
     /**
 240  
      * Returns <tt>true</tt> if this is a revision
 241  
      * at the very beginning of the log timespan which is
 242  
      * only a container for the number of code lines at the beginning
 243  
      * of the log and not a real revision committed by an author.
 244  
      * @return <code>true</code> if this revision exists
 245  
      * only for StatCvs bookkeeping purposes
 246  
      */
 247  
     public boolean isBeginOfLog() {
 248  0
         return type == TYPE_BEGIN_OF_LOG;
 249  
     }
 250  
 
 251  
     /**
 252  
      * {@inheritDoc}
 253  
      */
 254  
     public String toString() {
 255  0
         return this.author.getName() + " - " + this.revisionNumber;
 256  
     }
 257  
 
 258  
     /**
 259  
      * Returns the file which was changed by this revision.
 260  
      * @return the file
 261  
      */
 262  
     public VersionedFile getFile() {
 263  0
         return file;
 264  
     }
 265  
 
 266  
     /**
 267  
      * Returns the predecessor of this revision or <tt>null</tt> if it
 268  
      * is the first revision for the file.
 269  
      * @return the predecessor of this revision
 270  
      */
 271  
     public Revision getPreviousRevision() {
 272  0
         return file.getPreviousRevision(this);
 273  
     }
 274  
 
 275  
     /**
 276  
      * Returns a list of {@link SymbolicName}s of this revision or null if
 277  
      * the revision has no symbolic names. The list is ordered from 
 278  
      * latest to oldest.
 279  
      *
 280  
      * @return list of symbolic names 
 281  
      */
 282  
     public SortedSet getSymbolicNames() {
 283  0
         return symbolicNames;
 284  
     }
 285  
 
 286  
     /**
 287  
      * Compares this revision to another revision. A revision is considered
 288  
      * smaller if its date is smaller. If the dates are identical, the filename,
 289  
      * author name, revision number and comment will be used to break the tie.
 290  
      */
 291  
     public int compareTo(final Object other) {
 292  0
         if (this == other) {
 293  0
             return 0;
 294  
         }
 295  0
         final Revision otherRevision = (Revision) other;
 296  0
         int result = date.compareTo(otherRevision.getDate());
 297  0
         if (result != 0) {
 298  0
             return result;
 299  
         }
 300  0
         result = file.getFilenameWithPath().compareTo(otherRevision.getFile().getFilenameWithPath());
 301  0
         if (result != 0) {
 302  0
             return result;
 303  
         }
 304  0
         result = revisionNumber.compareTo(otherRevision.getRevisionNumber());
 305  0
         if (result != 0) {
 306  0
             return result;
 307  
         }
 308  0
         if (author != null && otherRevision.getAuthor() != null) {
 309  0
             result = author.compareTo(otherRevision.getAuthor());
 310  0
             if (result != 0) {
 311  0
                 return result;
 312  
             }
 313  
         }
 314  0
         if (comment != null && otherRevision.getComment() != null) {
 315  0
             return comment.compareTo(otherRevision.getComment());
 316  
         }
 317  0
         return 1;
 318  
     }
 319  
 
 320  
     public boolean equals(final Object rhs) {
 321  0
         if (rhs == null) {
 322  0
             return false;
 323  
         }
 324  0
         if (!(rhs instanceof Revision)) {
 325  0
             return false;
 326  0
         }
 327  0
         final Revision that = (Revision) rhs;
 328  
 
 329  0
         boolean eq = getDate().equals(that.getDate());
 330  
 
 331  0
         if (eq) {
 332  0
             eq = file.getFilenameWithPath().equals(that.file.getFilenameWithPath());
 333  
         }
 334  0
         if (eq) {
 335  0
             eq = revisionNumber.equals(that.getRevisionNumber());
 336  0
         }
 337  0
         if (eq) {
 338  0
             eq = author != null && author.equals(that.getAuthor());
 339  0
         }
 340  0
         return eq;
 341  
     }
 342  0
 
 343  
     public int hashCode() {
 344  0
         return getDate().hashCode() + file.hashCode() + revisionNumber.hashCode();
 345  
     }
 346  
 
 347  
     //TODO: remove all deprecated methods when they are no longer used by StatCvs-XML
 348  
 
 349  0
     /**
 350  0
      * @deprecated Use {@link #getLinesDelta()} and {@link #getReplacedLines()} instead.
 351  
      */
 352  0
     public int getLinesAdded() {
 353  0
         if (isInitialRevision() && getPreviousRevision() != null) {
 354  0
             return 0;
 355  
         }
 356  0
         return getNewLines();
 357  
     }
 358  
 
 359  0
     /**
 360  
      * @deprecated Use {@link #getLinesDelta()} and {@link #getReplacedLines()} instead.
 361  
      */
 362  
     public int getLinesRemoved() {
 363  0
         if (isDead()) {
 364  0
             return 0;
 365  
         }
 366  0
         if (getLinesDelta() < 0) {
 367  0
             return -getLinesDelta() + getReplacedLines();
 368  
         }
 369  0
         return getReplacedLines();
 370  
     }
 371  
 
 372  
     /**
 373  0
      * @deprecated Use {@link #getLines()} instead.
 374  
      */
 375  
     public int getLinesOfCode() {
 376  0
         if (isDead() && getPreviousRevision() != null) {
 377  0
             return getPreviousRevision().getLines();
 378  
         }
 379  0
         return getLines();
 380  0
     }
 381  0
 
 382  
     /**
 383  0
      * @deprecated Use {@link #getLines()} instead.
 384  
      */
 385  
     public int getEffectiveLinesOfCode() {
 386  0
         return getLines();
 387  
     }
 388  
 
 389  
     /**
 390  0
      * @deprecated Use {@link #getLinesDelta()} instead.
 391  
      */
 392  
     public int getLinesOfCodeChange() {
 393  0
         return getLinesDelta();
 394  
     }
 395  
 
 396  
     /**
 397  0
      * @deprecated Use {@link #getNewLines()} instead.
 398  
      */
 399  
     public int getLineValue() {
 400  0
         return getNewLines();
 401  
     }
 402  
 
 403  
     /**
 404  
      * @deprecated Use {@link #getReplacedLines()} and {@link #getLinesDelta} instead.
 405  
      */
 406  
     public int getRemovingValue() {
 407  0
         if (getLinesDelta() > 0) {
 408  0
             return getReplacedLines();
 409  
         }
 410  0
         return -getLinesDelta() + getReplacedLines();
 411  
     }
 412  
 
 413  
     /**
 414  
      * @deprecated Use {@link #getFileCountDelta()} instead.
 415  
      */
 416  
     public int getFileCountChange() {
 417  0
         return getFileCountDelta();
 418  
     }
 419  
 
 420  
     /**
 421  
      * @deprecated Use {@link #getRevisionNumber()} instead.
 422  
      */
 423  
     public String getRevision() {
 424  0
         return getRevisionNumber();
 425  
     }
 426  
 }