1 package net.sf.statcvs.reports;
2
3 import net.sf.statcvs.model.Revision;
4
5 import org.jfree.data.time.Hour;
6 import org.jfree.data.time.Minute;
7 import org.jfree.data.time.RegularTimePeriod;
8 import org.jfree.data.time.TimeSeries;
9
10 /**
11 * Builds a <tt>BasicTimesSeries</tt> for the LOC history of a set of
12 * revisions. All revisions that should be counted must be passed to
13 * the {@link #addRevision} method. When all revisions have been passed
14 * to this method, a <tt>BasicTimeSeries</tt> can
15 * be obtained from {@link #getTimeSeries} and can be added to a chart.
16 *
17 * TODO: Replace by a custom LocTimeSeriesReport
18 *
19 * @author Richard Cyganiak
20 * @version $Id: LOCSeriesBuilder.java,v 1.4 2008/04/02 11:22:15 benoitx Exp $
21 **/
22 public class LOCSeriesBuilder {
23
24 private final TimeSeries series;
25 private boolean hasRevisions = false;
26 private Minute minute;
27 private int loc = 0;
28 private boolean finished = false;
29 private final boolean countEffective;
30 private int maximum = 0;
31
32 /**
33 * Creates a new <tt>LOCSeriesBuilder</tt>
34 * @param seriesTitle the title for the time series
35 * @param countEffective If <tt>true</tt>, the effective LOC number will
36 * be counted. If <tt>false</tt>, the contributed
37 * value of new lines will be counted.
38 */
39 public LOCSeriesBuilder(final String seriesTitle, final boolean countEffective) {
40 series = new TimeSeries(seriesTitle, Minute.class);
41 this.countEffective = countEffective;
42 }
43
44 /**
45 * Adds a revision to the time series. The revision must
46 * be at a later date than all previously added revisions.
47 * @param revision the revision to add to the series
48 */
49 public void addRevision(final Revision revision) {
50 if (finished) {
51 throw new IllegalStateException("can't add more revisions after getTimeSeries()");
52 }
53 if (!hasRevisions) {
54 if (revision.isBeginOfLog()) {
55 loc += revision.getLines();
56 return;
57 }
58 minute = new Minute(revision.getDate());
59
60
61 RegularTimePeriod previousMinute = minute.previous();
62 if (previousMinute == null) {
63 previousMinute = new Minute(Minute.LAST_MINUTE_IN_HOUR, (Hour) minute.getHour().previous());
64 }
65
66 series.add(previousMinute, loc);
67 hasRevisions = true;
68 } else {
69 final Minute currentMinute = new Minute(revision.getDate());
70 if (!currentMinute.equals(minute)) {
71 series.add(minute, loc);
72 minute = currentMinute;
73 }
74 }
75 if (countEffective) {
76 loc += revision.getLinesDelta();
77 } else {
78 loc += revision.getNewLines();
79 }
80 this.maximum = Math.max(this.maximum, this.loc);
81 }
82
83 /**
84 * gets the finished time series. Should not be called before
85 * all revisions have been added.
86 * @return the resulting <tt>BasicTimeSeries</tt> or <tt>null</tt>
87 * if no LOC data is available for the revision set
88 */
89 public TimeSeries getTimeSeries() {
90 if (!hasRevisions) {
91 return null;
92 }
93 if (!finished) {
94 series.add(minute, loc);
95 series.add(minute.next(), loc);
96 finished = true;
97 }
98 return series;
99 }
100
101 /**
102 * @return The maximum value over the lifetime of the series
103 */
104 public int getMaximum() {
105 return this.maximum;
106 }
107 }