Coverage Report - net.sf.statcvs.input.CommitListBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
CommitListBuilder
96%
26/27
95%
19/20
1.75
 
 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  
         $Name:  $ 
 21  
         Created on $Date: 2008/04/02 11:22:15 $ 
 22  
 */
 23  
 package net.sf.statcvs.input;
 24  
 
 25  
 import java.util.Date;
 26  
 import java.util.HashMap;
 27  
 import java.util.Iterator;
 28  
 import java.util.LinkedList;
 29  
 import java.util.List;
 30  
 import java.util.Map;
 31  
 import java.util.SortedSet;
 32  
 
 33  
 import net.sf.statcvs.model.Commit;
 34  
 import net.sf.statcvs.model.Revision;
 35  
 
 36  
 /**
 37  
  * Takes a set of revisions, and builds a <code>List</code> of 
 38  
  * {@link Commit}s from it. The result list is sorted by date.
 39  
  * 
 40  
  * The implementation allows for a tolerance of several minutes
 41  
  * between individual file commits, but author and message must be identical.
 42  
  * 
 43  
  * @author Richard Cyganiak
 44  
  * @version $Id: CommitListBuilder.java,v 1.5 2008/04/02 11:22:15 benoitx Exp $
 45  
  */
 46  
 public class CommitListBuilder {
 47  
     private static final int MAX_TIME_BETWEEN_CHANGES_MILLISECONDS = 300000;
 48  
 
 49  
     private final Iterator revisions;
 50  208
     private final Map currentCommits = new HashMap();
 51  
     private List commits;
 52  
 
 53  
     /**
 54  
      * Creates a new instance using the given set of {@link Revision}s.
 55  
      * The set must be sorted by date, oldest first.
 56  
      * 
 57  
      * @param revisions a set of {@link Revision}s
 58  
      */
 59  
     public CommitListBuilder(final SortedSet revisions) {
 60  208
         this(revisions.iterator());
 61  208
     }
 62  
 
 63  208
     public CommitListBuilder(final Iterator revisions) {
 64  208
         this.revisions = revisions;
 65  208
     }
 66  
 
 67  
     /**
 68  
      * Creates a <code>List</code> of {@link Commit}s from the source iterator.
 69  
      * The result list will be sorted by date.
 70  
      * 
 71  
      * @return a new list of {@link Commit} objects
 72  
      */
 73  
     public List createCommitList() {
 74  208
         if (commits != null) {
 75  0
             return commits;
 76  
         }
 77  
 
 78  208
         commits = new LinkedList();
 79  624
         while (revisions.hasNext()) {
 80  416
             processRevision((Revision) revisions.next());
 81  
         }
 82  208
         return commits;
 83  
     }
 84  
 
 85  
     protected void processRevision(final Revision rev) {
 86  416
         if (rev.getAuthor() == null) {
 87  32
             return;
 88  
         }
 89  384
         final Commit commit = (Commit) currentCommits.get(rev.getAuthor());
 90  384
         if (commit == null || !isSameCommit(commit, rev)) {
 91  352
             addNewCommit(rev);
 92  
         } else {
 93  32
             addRevToCommit(commit, rev);
 94  
         }
 95  384
     }
 96  
 
 97  
     protected void addNewCommit(final Revision rev) {
 98  352
         final Commit newCommit = new Commit(rev);
 99  352
         currentCommits.put(rev.getAuthor(), newCommit);
 100  352
         commits.add(newCommit);
 101  352
     }
 102  
 
 103  
     protected void addRevToCommit(final Commit commit, final Revision rev) {
 104  32
         commit.addRevision(rev);
 105  32
     }
 106  
 
 107  
     /**
 108  
      * Returns <code>true</code> if change is part of the commit, that is if
 109  
      * they have the same author, the same message, and are within the same
 110  
      * timeframe.
 111  
      * 
 112  
      * @param commit the commit
 113  
      * @param rev the revision to check against this commit
 114  
      * @return <code>true</code> if change is part of this commit
 115  
      */
 116  
     public static boolean isSameCommit(final Commit commit, final Revision rev) {
 117  168
         return commit.getAuthor().equals(rev.getAuthor()) && commit.getComment().equals(rev.getComment()) && isInTimeFrame(commit, rev.getDate());
 118  
     }
 119  
 
 120  
     /**
 121  
      * Returns <code>true</code> if the date lies within the timespan of
 122  
      * the commit, plus/minus a tolerance.
 123  
      * 
 124  
      * @param date the date to check against this commit
 125  
      * @return <code>true</code> if the date lies within the timespan of the commit
 126  
      */
 127  
     public static boolean isInTimeFrame(final Commit commit, final Date date) {
 128  152
         return date.getTime() > (commit.getDate().getTime() - MAX_TIME_BETWEEN_CHANGES_MILLISECONDS)
 129  
                 && (date.getTime() < commit.getDate().getTime() + MAX_TIME_BETWEEN_CHANGES_MILLISECONDS);
 130  
     }
 131  
 }