* populate the data, filling in blank spots. The full list of interval DateTimes is used to create every row in the
* query range. Then the iterator
*/
for (final DateTime rowTime : reportTimes) {
// create the row
final TableRow row = new TableRow();
// add the date to the first cell
final Value dateTimeValue;
switch (dateTimeColumnType) {
case DATE: {
dateTimeValue = new DateValue(rowTime.getYear(), rowTime.getMonthOfYear()-1, rowTime.getDayOfMonth());
break;
}
case TIMEOFDAY: {
dateTimeValue = new TimeOfDayValue(rowTime.getHourOfDay(), rowTime.getMinuteOfHour(), 0);
break;
}
default: {
dateTimeValue = new DateTimeValue(rowTime.getYear(), rowTime.getMonthOfYear()-1, rowTime.getDayOfMonth(), rowTime.getHourOfDay(), rowTime.getMinuteOfHour(), 0, 0);
break;
}
}
row.addCell(new TableCell(dateTimeValue));
for (final PeekingIterator<T> groupedAggregationIteratorEntry : groupedAggregationIterators.values()) {
List<Value> values = null;
if (groupedAggregationIteratorEntry.hasNext()) {
final T aggr = groupedAggregationIteratorEntry.peek();
if (rowTime.equals(aggr.getDateTime())) {
//Data is for the correct time slot, advance the iterator
groupedAggregationIteratorEntry.next();
values = createRowValues(aggr, form);
}
}
//Gap in the data, fill it in using a null aggregation
if (values == null) {
values = createRowValues(null, form);
}
//Add the values to the row
for (final Value value : values) {
row.addCell(value);
}
}
table.addRow(row);
}