Coverage Report - net.sf.statsvn.output.ChurnPageMaker
 
Classes in this File Line Coverage Branch Coverage Complexity
ChurnPageMaker
0%
0/44
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.statsvn.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
                 Map changePerRevision = new HashMap();
 73  0
                 SortedSet revisions = config.getRepository().getRevisions();
 74  0
                 for (Iterator it = revisions.iterator(); it.hasNext();) {
 75  0
                         Revision rev = (Revision) it.next();
 76  0
                         Date dateToUse = blastTime(rev.getDate());
 77  0
                         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
                 List annotations = SymbolicNameAnnotation.createAnnotations(config.getRepository().getSymbolicNames());
 86  0
                 TimeSeries timeLine = new TimeSeries(Messages.getString("CHURN_TOUCHED_LINE"), Day.class);
 87  
 
 88  0
                 for (Iterator it = changePerRevision.entrySet().iterator(); it.hasNext();) {
 89  0
                         Map.Entry entry = (Entry) it.next();
 90  
 
 91  0
                         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
                 TimeSeries locSeries = getLOCTimeSeries(revisions, Messages.getString("TIME_LOC_SUBTITLE"));
 96  
 
 97  0
                 LOCChurnChartMaker chart = new LOCChurnChartMaker(config, timeLine, locSeries, Messages.getString("LOC_CHURN_CHART_TITLE"), "locandchurn.png", config
 98  
                         .getLargeChartSize(), annotations);
 99  0
                 return chart.toFile();
 100  
         }
 101  
 
 102  
         private Date blastTime(final Date date) {
 103  0
                 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(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  
 }