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 }