1   package com.stateofflow.eclipse.metrics.export.html.histogram;
2   
3   import java.util.ArrayList;
4   import java.util.Arrays;
5   import java.util.List;
6   import java.util.Set;
7   import java.util.SortedSet;
8   import java.util.TreeMap;
9   import java.util.TreeSet;
10  
11  import org.jfree.data.AbstractDataset;
12  import org.jfree.data.CategoryDataset;
13  
14  import com.stateofflow.eclipse.metrics.collator.MetricsCollator;
15  import com.stateofflow.eclipse.metrics.location.MetricLocation;
16  import com.stateofflow.eclipse.metrics.metric.MetricId;
17  import com.stateofflow.eclipse.metrics.util.Counter;
18  import com.stateofflow.eclipse.metrics.util.CounterMap;
19  
20  public final class MetricsDataset extends AbstractDataset implements CategoryDataset {
21      private static final Range[] ROW_KEYS = {Range.OUT, Range.IN};
22  
23      private final int preferredUpperBound;
24      private final CounterMap<Category> categoryToYValueMap;
25  
26      public MetricsDataset(final MetricsCollator collator, final MetricId metricId, final int preferredUpperBound) {
27          this.preferredUpperBound = preferredUpperBound;
28          categoryToYValueMap = new CounterMap<Category>(new TreeMap<Category, Counter>());
29  
30          initialise(collator, metricId);
31      }
32  
33      private void add(final MetricsCollator collator, final MetricLocation location, final MetricId metricId) {
34          if (collator.hasMetric(location, metricId)) {
35              incrementCategoryForValue(collator.getMetric(location, metricId).getValue());
36          }
37      }
38  
39      private void collate(final MetricsCollator collator, final MetricId metricId) {
40          collator.forEach(new MetricLocation.Closure() {
41              public void execute(final MetricLocation location) {
42                  add(collator, location, metricId);
43              }
44          });
45      }
46  
47      private void fillInMissingCategories() {
48          final Category smallestCategory = getCategories().first();
49          for (Category category = getCategories().last(); !smallestCategory.equals(category); category = category.predecessor()) {
50              categoryToYValueMap.put(category, 0);
51          }
52      }
53  
54      private SortedSet<Category> getCategories() {
55          final Set<Category> keySet = categoryToYValueMap.keySet();
56          return keySet instanceof SortedSet ? (SortedSet<Category>) keySet : new TreeSet<Category>(keySet);
57      }
58  
59      public int getColumnCount() {
60          return categoryToYValueMap.size();
61      }
62  
63      @SuppressWarnings("unchecked")
64      public int getColumnIndex(final Comparable category) {
65          return getColumnKeys().indexOf(category);
66      }
67  
68      public Category getColumnKey(final int index) {
69          return getColumnKeys().get(index);
70      }
71  
72      public List<Category> getColumnKeys() {
73          return new ArrayList<Category>(getCategories());
74      }
75  
76      public int getRowCount() {
77          return 2;
78      }
79  
80      @SuppressWarnings("unchecked")
81      public int getRowIndex(final Comparable key) {
82          return ((Range) key).getIndex();
83      }
84  
85      public Range getRowKey(final int index) {
86          return MetricsDataset.ROW_KEYS[index];
87      }
88  
89      public List<Range> getRowKeys() {
90          return Arrays.asList(MetricsDataset.ROW_KEYS);
91      }
92  
93      @SuppressWarnings("unchecked")
94      public Number getValue(final Comparable range, final Comparable category) {
95          return new Integer(((Range) range).getValue((Category) category, categoryToYValueMap));
96      }
97  
98      public Number getValue(final int row, final int column) {
99          return getValue(getRowKey(row), getColumnKey(column));
100     }
101 
102     private void incrementCategoryForValue(final int value) {
103         categoryToYValueMap.put(new Category(value, preferredUpperBound), 1);
104     }
105 
106     private void initialise(final MetricsCollator collator, final MetricId metricId) {
107         collate(collator, metricId);
108         fillInMissingCategories();
109     }
110 }