Map testRuns = new HashMap(); // from test name to resultholders
Set testNames = new TreeSet(String.CASE_INSENSITIVE_ORDER);
for (int i = 0; i < results.length; ++i) {
Enumeration en = results[i].getResultEnumeration();
while (en.hasMoreElements()) {
ResultHolder rh = (ResultHolder)en.nextElement();
String name = rh.getName();
testNames.add(name);
ArrayList list = (ArrayList)testRuns.get(name);
if (list == null) {
list = new ArrayList();
testRuns.put(name, list);
}
list.add(rh);
}
}
w.println("<hr size='1' width='60%'/>");
w.println("<br/>");
w.println("<table align='center' cols='2' cellspacing='0' cellpadding='0' border='0' width='80%'>");
Iterator iter = testNames.iterator();
while (iter.hasNext()) {
String name = (String)iter.next();
w.println("<tr bgcolor='#aaaaaa'><th colspan='2'>"+name+"</th></tr>");
double bestScore = 0;
// get sorted list of variable options for this test
// optionMap maps each option to a value map. the value map contains all the values,
// sorted depending on the value type (numeric or string). it maps
// from each (string) value to a list of all the resultholders for that value
// value.
Map optionMap = new TreeMap(String.CASE_INSENSITIVE_ORDER);
ArrayList list = (ArrayList)testRuns.get(name);
Iterator riter = list.iterator();
while (riter.hasNext()) {
ResultHolder rh = (ResultHolder)riter.next();
Hashtable options = rh.getOptions();
Set entries = options.entrySet();
Iterator eiter = entries.iterator();
while (eiter.hasNext()) {
Map.Entry e = (Map.Entry)eiter.next();
Object key = e.getKey();
if (ResultHolder.commonkeys.contains(key)) {
continue;
}
Object val = e.getValue();
Map vmap = (Map)optionMap.get(key);
if (vmap == null) {
// determine how to sort
boolean numeric = false;
try {
Integer.parseInt((String)val);
numeric = true;
}
catch (NumberFormatException pe) {
}
Comparator c = numeric ? numericComparator : String.CASE_INSENSITIVE_ORDER;
vmap = new TreeMap(c);
optionMap.put(key, vmap);
}
ArrayList vlist = (ArrayList)vmap.get(val);
if (vlist == null) {
vlist = new ArrayList();
vmap.put(val, vlist);
}
vlist.add(rh);
double score = rh.getScore();
if (score > bestScore) {
bestScore = score;
}
}
}
Iterator oi = optionMap.keySet().iterator();
while (oi.hasNext()) {
String optionName = (String)oi.next();
Map optionValues = (Map)optionMap.get(optionName);
if (optionValues.size() == 1) continue; // don't group by this if only one value
StringBuffer grouping = new StringBuffer();
grouping.append("Grouped by " + optionName + ", Result set");
Iterator oi2 = optionMap.keySet().iterator();
while (oi2.hasNext()) {
String oname2 = (String)oi2.next();
if (oname2.equals(optionName)) continue;
Map ov2 = (Map)optionMap.get(oname2);
if (ov2.size() == 1) continue;
grouping.append(", " + oname2);
Iterator ov2i = ov2.entrySet().iterator();
grouping.append(" (");
boolean comma = false;
while (ov2i.hasNext()) {
if (comma) grouping.append(", ");
grouping.append(((Map.Entry)ov2i.next()).getKey());
comma = true;
}
grouping.append(")");
}
w.println("<tr><td colspan='2'> </td></tr>");
w.println("<tr><td colspan='2'><b>" + grouping.toString() + "</b></td></tr>");
Iterator vi = optionValues.keySet().iterator();
while (vi.hasNext()) {
String valueName = (String)vi.next();
w.print("<tr><td align='right' valign='center' width='10%'>"+valueName+" </td><td>");
ArrayList resultList = (ArrayList)optionValues.get(valueName);
// sort the result list in order of the sets the results come from
// we count on this being a stable sort, otherwise we'd have to also sort
// within each result set on all other variables
Comparator c = new Comparator() {
public int compare(Object lhs, Object rhs) {
ResultSetHolder lh = ((ResultHolder)lhs).rsh;
ResultSetHolder rh = ((ResultHolder)rhs).rsh;
int li = -1;
for (int k = 0; k < results.length; ++k) {
if (results[k] == lh) {
li = k;
break;
}
}
int ri = -1;
for (int k = 0; k < results.length; ++k) {
if (results[k] == rh) {
ri = k;
break;
}
}
return li - ri;
}
};
w.println(" <div style='height: 5'> </div>");
ResultHolder[] sorted = new ResultHolder[resultList.size()];
sorted = (ResultHolder[])resultList.toArray(sorted);
Arrays.sort(sorted, c);
for (int k = 0; k < sorted.length; ++k) {
ResultHolder holder = sorted[k];
String color = null;
for (int n = 0; n < results.length; ++n) {
if (results[n] == holder.rsh) {
color = hexColor[n];
}
}
double score = holder.getScore();
int pix = 0;
if (bestScore > 1) {
double scale = logScale
? Math.log(score)/Math.log(bestScore)
: (score)/(bestScore);