1 package net.sf.statcvs.reports;
2
3 import java.util.Iterator;
4 import java.util.regex.Matcher;
5 import java.util.regex.Pattern;
6
7 import net.sf.statcvs.Messages;
8 import net.sf.statcvs.model.VersionedFile;
9 import net.sf.statcvs.output.ReportConfig;
10 import net.sf.statcvs.reportmodel.IntegerColumn;
11 import net.sf.statcvs.reportmodel.RatioColumn;
12 import net.sf.statcvs.reportmodel.SimpleTextColumn;
13 import net.sf.statcvs.reportmodel.Table;
14 import net.sf.statcvs.util.IntegerMap;
15
16 public class FileTypeReport implements TableReport {
17 private final static String NON_CODE_FILES = "@@@NON-CODE FILES";
18 private final static String NO_EXTENSION = "@@@NO EXTENSION";
19 private final static Pattern extensionPattern = Pattern.compile(".*[^.]\\.([CH]|[a-z0-9_-]+)");
20
21 private final ReportConfig config;
22 private Table table;
23
24 public FileTypeReport(final ReportConfig config) {
25 this.config = config;
26 }
27
28 public void calculate() {
29 final IntegerMap lines = new IntegerMap();
30 final IntegerMap counts = new IntegerMap();
31 lines.put(NON_CODE_FILES, 0);
32 lines.put(NON_CODE_FILES, 0);
33 Iterator it = this.config.getRepository().getFiles().iterator();
34 while (it.hasNext()) {
35 final VersionedFile file = (VersionedFile) it.next();
36 if (file.isDead()) {
37 continue;
38 }
39 if (file.getCurrentLinesOfCode() == 0) {
40 counts.addInt(NON_CODE_FILES, 1);
41 } else {
42 lines.addInt(getExtension(file.getFilename()), file.getCurrentLinesOfCode());
43 counts.addInt(getExtension(file.getFilename()), 1);
44 }
45 }
46
47 final SimpleTextColumn typeCol = new SimpleTextColumn(Messages.getString("FILE_TYPE"));
48 typeCol.setTotal("Totals");
49 final IntegerColumn filesCol = new IntegerColumn(Messages.getString("FILES"));
50 final IntegerColumn linesCol = new IntegerColumn(Messages.getString("FILE_LOC"));
51 this.table = new Table("File Extensions");
52 this.table.setShowTotals(true);
53 this.table.setKeysInFirstColumn(true);
54 this.table.addColumn(typeCol);
55 this.table.addColumn(filesCol);
56 this.table.addColumn(linesCol);
57 this.table.addColumn(new RatioColumn(Messages.getString("LOC_PER_FILE"), linesCol, filesCol));
58
59 double cumulativePercent = 0;
60 int otherLines = 0;
61 int otherCount = 0;
62 it = lines.iteratorSortedByValueReverse();
63 while (it.hasNext()) {
64 final String extension = (String) it.next();
65 if (NO_EXTENSION.equals(extension) || NON_CODE_FILES.equals(extension)) {
66 continue;
67 }
68 if (cumulativePercent < 80 || this.table.getRowCount() < 10) {
69 typeCol.addValue("*." + extension);
70 filesCol.addValue(counts.get(extension));
71 linesCol.addValue(lines.get(extension));
72 cumulativePercent += lines.getPercent(extension);
73 } else {
74 otherCount += counts.get(extension);
75 otherLines += lines.get(extension);
76 }
77 }
78 counts.addInt(NO_EXTENSION, otherCount);
79 lines.addInt(NO_EXTENSION, otherLines);
80 if (counts.get(NO_EXTENSION) > 0) {
81 typeCol.addValue("Others");
82 filesCol.addValue(counts.get(NO_EXTENSION));
83 linesCol.addValue(lines.get(NO_EXTENSION));
84 }
85 if (counts.get(NON_CODE_FILES) > 0) {
86 typeCol.addValue("Non-Code Files");
87 filesCol.addValue(counts.get(NON_CODE_FILES));
88 linesCol.addValue(lines.get(NON_CODE_FILES));
89 }
90 }
91
92 public Table getTable() {
93 return this.table;
94 }
95
96 private String getExtension(final String fileName) {
97 final Matcher m = extensionPattern.matcher(fileName);
98 if (!m.matches()) {
99 return NO_EXTENSION;
100 }
101 return m.group(1);
102 }
103 }