001 package org.hackystat.projectbrowser.page.dailyprojectdata.coverage; 002 003 import java.io.Serializable; 004 import java.util.ArrayList; 005 import java.util.List; 006 import java.util.logging.Logger; 007 008 import org.hackystat.dailyprojectdata.resource.coverage.jaxb.ConstructData; 009 import org.hackystat.projectbrowser.ProjectBrowserApplication; 010 import org.hackystat.projectbrowser.page.dailyprojectdata.detailspanel.DailyProjectDetailsPanel; 011 import org.hackystat.sensorbase.resource.projects.jaxb.Project; 012 import org.hackystat.utilities.stacktrace.StackTrace; 013 014 /** 015 * Data structure for representing coverage information about a single project. 016 * This representation includes the Project, plus the number of classes in the project with 017 * coverage in each of five buckets: 0-20%, 21-40%, 41-60%, 61-80%, and 81-100%. 018 * 019 * @author Philip Johnson 020 * @author Shaoxuan Zhang 021 */ 022 public class CoverageData implements Serializable { 023 024 /** Support serialization. */ 025 private static final long serialVersionUID = 1L; 026 027 /** The project whose data is kept in this instance. */ 028 private Project project; 029 030 /** The five buckets for this data. */ 031 private List<List<ConstructData>> buckets = new ArrayList<List<ConstructData>>(); 032 033 /** The total number of entries added across all buckets. */ 034 private int total = 0; 035 036 /** 037 * Creates a new CoverageData instance and initializes the buckets to zero. 038 * @param name The name of the Project associated with this instance. 039 */ 040 public CoverageData(Project name) { 041 this.project = name; 042 for (int i = 0; i < 5; i++) { 043 buckets.add(new ArrayList<ConstructData>()); 044 } 045 } 046 047 /** 048 * Increments the given bucket by 1. 049 * @param bucket The bucket number. 050 * @param data The Construct Data. 051 */ 052 private void incrementBucket(int bucket, ConstructData data) { 053 buckets.get(bucket).add(data); 054 this.total++; 055 } 056 057 /** 058 * Updates this CoverageData instance with information about the covered/uncovered information 059 * for a given instance in the Project. 060 * @param data The construct data. 061 */ 062 public void addEntry(ConstructData data) { 063 064 int numCovered = data.getNumCovered(); 065 int numUncovered = data.getNumUncovered(); 066 // If no method level coverage, ignore. 067 if ((numCovered == 0) && (numUncovered == 0)) { 068 return; 069 } 070 try { 071 double percent = (double)numCovered / (double)(numCovered + numUncovered); 072 if (percent <= 0.20) { 073 incrementBucket(0, data); 074 } 075 else if (percent <= 0.40) { 076 incrementBucket(1, data); 077 } 078 else if (percent <= 0.60) { 079 incrementBucket(2, data); 080 } 081 else if (percent <= 0.80) { 082 incrementBucket(3, data); 083 } 084 else { 085 incrementBucket(4, data); 086 } 087 } 088 catch (Exception e) { 089 Logger logger = ((ProjectBrowserApplication)ProjectBrowserApplication.get()).getLogger(); 090 logger.info("Error adding an entry to Coverage DPD: " + StackTrace.toString(e)); 091 } 092 } 093 094 /** 095 * Returns the current value of the specified bucket. 096 * @param bucket The bucket number, where 0 is the first one and 4 is the last one. 097 * @return The value inside the given bucket. 098 */ 099 public int getBucketValue(int bucket) { 100 return buckets.get(bucket).size(); 101 } 102 103 /** 104 * Returns the total number of entries across all buckets. 105 * @return The total number of entries. 106 */ 107 public int getTotal() { 108 return this.total; 109 } 110 111 /** 112 * Returns the total number of entries across all buckets as a string. 113 * @return The total number of entries. 114 */ 115 public String getTotalString() { 116 return String.valueOf(this.total); 117 } 118 119 /** 120 * Returns the bucket value as a percentage of the total number of entries across all buckets. 121 * Returns zero if there are no entries. 122 * @param bucket The bucket whose percentage is to be returned. 123 * @return The bucket as a percentage. 124 */ 125 public int getBucketPercentage(int bucket) { 126 if (getTotal() == 0) { 127 return 0; 128 } 129 else { 130 double percent = (double)getBucketValue(bucket) / (double)getTotal(); 131 return ((int) (percent * 100)); 132 } 133 } 134 135 /** 136 * Returns the current value of the specified bucket as a string. 137 * @param bucket The bucket number, where 0 is the first one and 4 is the last one. 138 * @return The value inside the given bucket. 139 */ 140 public String getBucketCountString(int bucket) { 141 return String.valueOf(getBucketValue(bucket)); 142 } 143 144 /** 145 * Returns the bucket percentage as a string. 146 * @param bucket The bucket. 147 * @return Its percentage as a string. 148 */ 149 public String getBucketPercentageString(int bucket) { 150 return getBucketPercentage(bucket) + "%"; 151 } 152 153 154 /** 155 * Return the project associated with this data. 156 * @return The project. 157 */ 158 public Project getProject() { 159 return project; 160 } 161 162 /** 163 * Returns a details panel containing information about this bucket. 164 * @param id The wicket id for this panel. 165 * @param bucket The bucket of interest. 166 * @param isCount True if the count should be returned, false if percentage. 167 * @return The DailyProjectDetailsPanel instance. 168 */ 169 public DailyProjectDetailsPanel getPanel(String id, int bucket, boolean isCount) { 170 DailyProjectDetailsPanel dpdPanel = 171 new DailyProjectDetailsPanel(id, "Coverage Data", 172 ((isCount) ? this.getBucketCountString(bucket) : this.getBucketPercentageString(bucket))); 173 dpdPanel.getModalWindow().setContent( 174 new CoverageDetailsPanel(dpdPanel.getModalWindow().getContentId(), 175 buckets.get(bucket))); 176 177 return dpdPanel; 178 } 179 }