1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package net.sf.statcvs.reports;
24
25 import java.util.ArrayList;
26 import java.util.Calendar;
27 import java.util.Collection;
28 import java.util.Date;
29 import java.util.Iterator;
30 import java.util.List;
31
32 import net.sf.statcvs.Messages;
33 import net.sf.statcvs.model.Author;
34 import net.sf.statcvs.model.Repository;
35 import net.sf.statcvs.model.Revision;
36 import net.sf.statcvs.output.ReportConfig;
37 import net.sf.statcvs.reportmodel.GenericColumn;
38 import net.sf.statcvs.reportmodel.IntegerColumn;
39 import net.sf.statcvs.reportmodel.Table;
40 import net.sf.statcvs.util.IntegerMap;
41
42 /**
43 * Convenience superclass for table reports related to last n months for authors and directories.
44 * Contains methods to calculate some common stuff for these tables.
45 * @author Lukasz Pekacki
46 * @author Benoit Xhenseval
47 * @version $Id: AbstractRollingLocTableReport.java,v 1.3 2009/03/09 22:21:36 benoitx Exp $
48 */
49 public abstract class AbstractRollingLocTableReport {
50 private static final int NUMBER_OF_MONTHS = 12;
51 /**
52 * Sort the authors table by name
53 * */
54 public static final int SORT_BY_NAME = 0;
55
56 /**
57 * Sort the authors table by lines of code
58 * */
59 public static final int SORT_BY_LINES = 1;
60
61 private final ReportConfig config;
62 private final Repository content;
63
64 private final List changesMaps;
65 private final List linesMaps;
66 private final IntegerMap authors = new IntegerMap();
67 private Date cutOff;
68
69 /**
70 * Constructor
71 * @param content render table on specified content
72 */
73 public AbstractRollingLocTableReport(final ReportConfig config) {
74 this.config = config;
75 this.content = config.getRepository();
76 changesMaps = new ArrayList(NUMBER_OF_MONTHS + 1);
77 linesMaps = new ArrayList(NUMBER_OF_MONTHS + 1);
78 for (int i = 0; i < NUMBER_OF_MONTHS + 1; i++) {
79 changesMaps.add(new IntegerMap());
80 linesMaps.add(new IntegerMap());
81 }
82 }
83
84 protected void calculateChangesAndLinesPerDeveloper(final Collection revs) {
85 final Iterator it = revs.iterator();
86 final Date last = content.getLastDate();
87 final Calendar cal = Calendar.getInstance();
88 cal.setTime(last);
89 cal.add(Calendar.MONTH, -NUMBER_OF_MONTHS + 1);
90 cal.set(Calendar.DAY_OF_MONTH, 1);
91 cal.add(Calendar.DAY_OF_MONTH, -1);
92 cal.set(Calendar.HOUR_OF_DAY, 23);
93 cal.set(Calendar.MINUTE, 59);
94 cal.set(Calendar.SECOND, 59);
95 cal.set(Calendar.MILLISECOND, 999);
96 cutOff = cal.getTime();
97
98
99 while (it.hasNext()) {
100 final Revision rev = (Revision) it.next();
101 if (rev.getAuthor() == null || !this.config.isDeveloper(rev.getAuthor())) {
102 continue;
103 }
104
105 final IntegerMap changesMap = findMap(cal, rev.getDate(), cutOff, changesMaps);
106 final IntegerMap linesMap = findMap(cal, rev.getDate(), cutOff, linesMaps);
107
108 changesMap.addInt(rev.getAuthor(), 1);
109 linesMap.addInt(rev.getAuthor(), rev.getNewLines());
110 authors.addInt(rev.getAuthor(), rev.getNewLines());
111 }
112 }
113
114 private IntegerMap findMap(final Calendar cal, final Date date, final Date cutOff, final List listOfMaps) {
115 if (date.compareTo(cutOff) < 0) {
116 return (IntegerMap) listOfMaps.get(0);
117 }
118
119 cal.setTime(cutOff);
120 final int cutOffMonth = cal.get(Calendar.MONTH) + 1;
121 cal.setTime(date);
122 final int monthRev = cal.get(Calendar.MONTH) + 1;
123
124 int idx = monthRev - cutOffMonth;
125
126 if (idx < 0) {
127 idx += 12;
128 }
129
130
131
132 if (idx == 0) {
133 idx = 12;
134 }
135
136 return (IntegerMap) listOfMaps.get(idx);
137 }
138
139 protected Table createChangesAndLinesTable(final GenericColumn keys, final GenericColumn keys2, final String summary) {
140 final Table result = new Table(summary);
141 keys.setTotal(Messages.getString("TOTALS"));
142 result.addColumn(keys);
143 if (keys2 != null) {
144 keys.setTotal("");
145 keys2.setTotal(Messages.getString("TOTALS"));
146 result.addColumn(keys2);
147 }
148 result.setKeysInFirstColumn(true);
149
150 final Calendar cal = Calendar.getInstance();
151 cal.setTime(cutOff);
152 final List columns = new ArrayList();
153 for (int i = 0; i < NUMBER_OF_MONTHS + 1; i++) {
154 String title = null;
155 if (i == 0) {
156 title = "Up to " + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.YEAR);
157 }
158 if (i != 0) {
159 cal.add(Calendar.MONTH, 1);
160 title = "" + (cal.get(Calendar.MONTH) + 1) + "/" + cal.get(Calendar.YEAR);
161 }
162 final IntegerColumn column = new IntegerColumn(title);
163 columns.add(column);
164 result.addColumn(column);
165 }
166
167 final Iterator it = authors.iteratorSortedByValueReverse();
168
169 while (it.hasNext()) {
170 final Object key = it.next();
171 keys.addValue(key);
172 if (keys2 != null) {
173 keys2.addValue(key);
174 }
175
176 for (int i = 0; i < NUMBER_OF_MONTHS + 1; i++) {
177 final IntegerMap linesMap = (IntegerMap) linesMaps.get(i);
178 ((IntegerColumn) columns.get(i)).addValue(linesMap.get(key));
179 }
180 }
181
182 if (result.getRowCount() > 1) {
183 result.setShowTotals(true);
184 }
185 return result;
186 }
187
188 protected Repository getContent() {
189 return content;
190 }
191
192 public int getDeveloperCount() {
193 int result = 0;
194 final Iterator it = getContent().getAuthors().iterator();
195 while (it.hasNext()) {
196 final Author author = (Author) it.next();
197 if (this.config.isDeveloper(author)) {
198 result++;
199 }
200 }
201 return result;
202 }
203 }