001    package org.hackystat.dailyprojectdata.resource.codeissue;
002    
003    import java.util.HashMap;
004    import java.util.Map;
005    import java.util.Set;
006    import java.util.logging.Logger;
007    
008    import org.hackystat.sensorbase.resource.sensordata.jaxb.Property;
009    import org.hackystat.sensorbase.resource.sensordata.jaxb.SensorData;
010    
011    /**
012     * IssueTypeCounter takes a set of CodeIssue SensorData all associated with a single tool,
013     * and constructs a data structure that maps issue types to their aggregate counts 
014     * across all tools.  
015     * 
016     * For example, consider two CodeIssue sensor data instances, illustrated below:
017     * <pre>
018     * [SensorData tool="Foo" sdt="CodeIssue" properties(["JavaDoc", "2"], ["Indentation", "3"])]
019     * [SensorData tool="Foo" sdt="CodeIssue" properties(["JavaDoc", "4"], ["NPE", "3"])]
020     * </pre>
021     * 
022     * We process these SensorData instances into the following IssueTypeCounter map:
023     * <pre>
024     * ["JavaDoc", 6]
025     * ["Indentation", 3]
026     * ["NPE", 3]
027     * </pre>
028     * 
029     * @author Philip Johnson
030     *
031     */
032    public class IssueTypeCounter {
033      
034      /** Maps issue names to their number of occurrences across all sensor data instances. */
035      private Map<String, Integer>type2count = new HashMap<String, Integer>();
036      
037      /**
038       * Constructs the IssueTypeCounter from the passed set of SensorData instances.
039       * @param dataSet The snapshot of sensor data instances for a given tool.
040       * @param logger The logger to get errors.
041       */
042      public IssueTypeCounter (Set<SensorData> dataSet, Logger logger) {
043        for (SensorData data : dataSet) {
044          for (Property property : data.getProperties().getProperty()) {
045            if (property.getKey().startsWith("Type_")) {
046              String typeName = null;
047              Integer typeNum = null;
048              try {
049                typeName = property.getKey().substring(5);
050                typeNum = Integer.parseInt(property.getValue());
051                // Now we have the type and value, so initialize our map if necessary.
052                if (type2count.get(typeName) == null) {
053                  type2count.put(typeName, 0);
054                }
055                // now increment this type value by the newly found number of occurrences.
056                type2count.put(typeName, typeNum + type2count.get(typeName));
057              }
058              catch (Exception e) {
059                logger.info("Problem with: " + typeName + " " + typeNum);
060              }
061            }
062          }
063        }
064      }
065      
066      /**
067       * Get the set of all types found from processing the sensor data snapshot.
068       * @return The set of CodeIssue types.
069       */
070      public Set<String> getTypes() {
071        return type2count.keySet();
072      }
073      
074      /**
075       * Return the number of CodeIssues of the given type found in this snapshot. 
076       * @param type The CodeIssue type.
077       * @return The count, or zero if this type was not found.
078       */
079      public int getCount(String type) {
080        Integer count = type2count.get(type);
081        return (count == null) ? 0 : count;
082      }
083      
084      
085    
086    }