Coverage Report - net.sf.statcvs.output.ChurnPageMaker
 
Classes in this File Line Coverage Branch Coverage Complexity
ChurnPageMaker
0%
0/43
0%
0/12
2
 
 1  
 /*
 2  
  StatSVN - SVN Subversion statistics generation 
 3  
  Copyright (C) 2006 Benoit Xhenseval
 4  
  http://www.statsvn.org
 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  
 */
 21  
 package net.sf.statcvs.output;
 22  
 
 23  
 import java.util.Calendar;
 24  
 import java.util.Date;
 25  
 import java.util.HashMap;
 26  
 import java.util.Iterator;
 27  
 import java.util.List;
 28  
 import java.util.Map;
 29  
 import java.util.SortedSet;
 30  
 import java.util.Map.Entry;
 31  
 
 32  
 import net.sf.statcvs.Messages;
 33  
 import net.sf.statcvs.charts.ChartImage;
 34  
 import net.sf.statcvs.charts.SymbolicNameAnnotation;
 35  
 import net.sf.statcvs.model.Revision;
 36  
 import net.sf.statcvs.output.ReportConfig;
 37  
 import net.sf.statcvs.pages.NavigationNode;
 38  
 import net.sf.statcvs.pages.Page;
 39  
 import net.sf.statcvs.reports.LOCSeriesBuilder;
 40  
 
 41  
 import org.jfree.data.time.Day;
 42  
 import org.jfree.data.time.TimeSeries;
 43  
 
 44  
 /**
 45  
  * A LOC and Churn Chart shows both the LOC and the number of lines touched per
 46  
  * day, this allows you to see the evolution of lines of code and the amount of
 47  
  * changes. A flat LOC with a lot of Churn implies a lot of refactoring, an
 48  
  * increase in LOC in line with churn implies new functionality.
 49  
  * 
 50  
  * @author Benoit Xhenseval (www.ObjectLab.co.uk)
 51  
  */
 52  
 public class ChurnPageMaker {
 53  
     private final ReportConfig config;
 54  
 
 55  
     /**
 56  
      * @see net.sf.statcvs.output.HTMLPage#HTMLPage(Repository)
 57  
      */
 58  0
     public ChurnPageMaker(final ReportConfig config) {
 59  0
         this.config = config;
 60  0
     }
 61  
 
 62  
     public NavigationNode toFile() {
 63  0
         final Page page = this.config.createPage("churn", Messages.getString("CHURN_TITLE"), Messages.getString("CHURN_TITLE"));
 64  0
         page.addRawContent("\n\n<!-- The LOC and Churn Report was designed by Benoit Xhenseval (http://www.objectlab.co.uk/open)-->");
 65  0
         page.addRawContent("\n<!-- Initially part of StatSVN -->\n\n");
 66  0
         page.addRawContent("<p>" + Messages.getString("CHURN_DESCRIPTION") + "</p>");
 67  0
         page.add(buildChart());
 68  0
         return page;
 69  
     }
 70  
 
 71  
     private ChartImage buildChart() {
 72  0
         final Map changePerRevision = new HashMap();
 73  0
         final SortedSet revisions = config.getRepository().getRevisions();
 74  0
         for (final Iterator it = revisions.iterator(); it.hasNext();) {
 75  0
             final Revision rev = (Revision) it.next();
 76  0
             final Date dateToUse = blastTime(rev.getDate());
 77  0
             final Integer changes = (Integer) changePerRevision.get(dateToUse);
 78  0
             if (changes == null) {
 79  0
                 changePerRevision.put(dateToUse, new Integer(Math.abs(getLineChanges(rev))));
 80  
             } else {
 81  0
                 changePerRevision.put(dateToUse, new Integer(Math.abs(changes.intValue()) + getLineChanges(rev)));
 82  
             }
 83  0
         }
 84  
 
 85  0
         final List annotations = SymbolicNameAnnotation.createAnnotations(config.getRepository().getSymbolicNames());
 86  0
         final TimeSeries timeLine = new TimeSeries(Messages.getString("CHURN_TOUCHED_LINE"), Day.class);
 87  
 
 88  0
         for (final Iterator it = changePerRevision.entrySet().iterator(); it.hasNext();) {
 89  0
             final Map.Entry entry = (Entry) it.next();
 90  
 
 91  
             //                        SvnConfigurationOptions.getTaskLogger().log("Churn on " + entry.getKey() + " ==> " + entry.getValue());
 92  0
             timeLine.add(new Day((Date) entry.getKey()), ((Integer) entry.getValue()).intValue());
 93  0
         }
 94  
 
 95  0
         final TimeSeries locSeries = getLOCTimeSeries(revisions, Messages.getString("TIME_LOC_SUBTITLE"));
 96  
 
 97  0
         final LOCChurnChartMaker chart = new LOCChurnChartMaker(config, timeLine, locSeries, Messages.getString("LOC_CHURN_CHART_TITLE"), "locandchurn.png",
 98  
                 config.getLargeChartSize(), annotations);
 99  0
         return chart.toFile();
 100  
     }
 101  
 
 102  
     private Date blastTime(final Date date) {
 103  0
         final Calendar cal = Calendar.getInstance();
 104  0
         cal.setTime(date);
 105  0
         cal.set(Calendar.MILLISECOND, 0);
 106  0
         cal.set(Calendar.HOUR_OF_DAY, 0);
 107  0
         cal.set(Calendar.MINUTE, 0);
 108  0
         cal.set(Calendar.SECOND, 0);
 109  0
         return cal.getTime();
 110  
     }
 111  
 
 112  
     private int getLineChanges(final Revision rev) {
 113  0
         if (rev.isDead()) {
 114  0
             return rev.getLinesDelta();
 115  
         }
 116  0
         return Math.abs(rev.getLinesDelta()) + 2 * rev.getReplacedLines();
 117  
     }
 118  
 
 119  
     private TimeSeries getLOCTimeSeries(final SortedSet revisions, final String title) {
 120  0
         final Iterator it = revisions.iterator();
 121  0
         final LOCSeriesBuilder locCounter = new LOCSeriesBuilder(title, true);
 122  0
         while (it.hasNext()) {
 123  0
             locCounter.addRevision((Revision) it.next());
 124  
         }
 125  0
         return locCounter.getTimeSeries();
 126  
     }
 127  
 }