001 package org.hackystat.dailyprojectdata.resource.filemetric; 002 003 import java.math.BigInteger; 004 import java.util.ArrayList; 005 import java.util.Iterator; 006 import java.util.List; 007 import javax.xml.datatype.XMLGregorianCalendar; 008 import org.hackystat.sensorbase.client.SensorBaseClient; 009 import org.hackystat.sensorbase.client.SensorBaseClientException; 010 import org.hackystat.sensorbase.resource.sensordata.jaxb.Property; 011 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData; 012 import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorDataRef; 013 import org.hackystat.utilities.time.period.Day; 014 import org.hackystat.utilities.tstamp.Tstamp; 015 016 /** 017 * Provides a facility for counting the FileMetrics associated with a 018 * SensorData. It only counts the FileMetrics from the 'last' run of the same 019 * tool. This ensures that the FileMetric size is the latest snapshot of the 020 * Project's size. 021 * 022 * The FileMetricCounter currently only looks at TotalLines. 023 * 024 * @author Cam Moore 025 * 026 */ 027 public class FileMetricCounter { 028 029 private String lastTool; 030 private XMLGregorianCalendar lastTime; 031 private List<SensorData> fileMetrics; 032 private SensorBaseClient sbClient; 033 private long totalLines; 034 035 /** 036 * Constructs a FileMetricCounter. 037 * 038 * @param client the SensorBaseClient to use to get the SensorData. 039 */ 040 public FileMetricCounter(SensorBaseClient client) { 041 this.lastTool = ""; 042 Day first = Day.getInstance(1000, 0, 1); // pick a very early Day 043 this.lastTime = Tstamp.makeTimestamp(first); 044 this.fileMetrics = new ArrayList<SensorData>(); 045 this.sbClient = client; 046 this.totalLines = 0; 047 } 048 049 /** 050 * Adds the SensorData to the list of FileMetrics if it is in the last run of the 051 * size counting tool. Updates the total lines value. If this sensor data represents 052 * a new run of a size counting tool then the total lines and list of file metrics is 053 * reset. 054 * @param ref a SensorDataRef, the sensor data to add. 055 */ 056 public void add(SensorDataRef ref) { 057 try { 058 SensorData data = sbClient.getSensorData(ref); 059 XMLGregorianCalendar refTime = data.getRuntime(); 060 if (Tstamp.equal(lastTime, refTime)) { 061 data = sbClient.getSensorData(ref); 062 if (lastTool.equals(data.getTool())) { 063 // only add data from the same tool. 064 List<Property> props = data.getProperties().getProperty(); 065 for (Iterator<Property> iter = props.iterator(); iter.hasNext();) { 066 Property prop = iter.next(); 067 if (prop.getKey().equals("TotalLines")) { 068 totalLines += Long.parseLong(prop.getValue()); 069 } 070 } 071 fileMetrics.add(data); 072 } 073 074 } 075 else if (Tstamp.greaterThan(refTime, lastTime)) { 076 // newer time so replace everything 077 lastTime = refTime; 078 fileMetrics = new ArrayList<SensorData>(); 079 totalLines = 0; 080 lastTool = data.getTool(); 081 List<Property> props = data.getProperties().getProperty(); 082 for (Iterator<Property> iter = props.iterator(); iter.hasNext();) { 083 Property prop = iter.next(); 084 if (prop.getKey().equals("TotalLines")) { 085 totalLines += Long.parseLong(prop.getValue()); 086 } 087 } 088 fileMetrics.add(data); 089 } 090 } 091 catch (SensorBaseClientException e) { 092 lastTool = ""; 093 } 094 095 } 096 097 /** 098 * @return The total lines as a BigInteger. 099 */ 100 public BigInteger getTotalLines() { 101 return BigInteger.valueOf(totalLines); 102 } 103 104 /** 105 * @return The individual FileMetrics SensorDataRefs. 106 */ 107 public List<SensorData> getFileMetrics() { 108 return fileMetrics; 109 } 110 111 /** 112 * @return The last time a size counting tool was run. 113 */ 114 public XMLGregorianCalendar getLastTime() { 115 return lastTime; 116 } 117 118 /** 119 * @param data a SensorData. 120 * @return The total lines in the given SensorData or 0 if the property "TotalLines" 121 * is undefined. 122 */ 123 public BigInteger getTotalLines(SensorData data) { 124 long totalLines = 0; 125 List<Property> props = data.getProperties().getProperty(); 126 for (Iterator<Property> iter = props.iterator(); iter.hasNext();) { 127 Property prop = iter.next(); 128 if (prop.getKey().equals("TotalLines")) { 129 totalLines += Long.parseLong(prop.getValue()); 130 } 131 } 132 return BigInteger.valueOf(totalLines); 133 } 134 }