{
// Ok, start bouncing through our list (only the visible part)
RowIterator rowIterator = model.getRowIterator(false);
// iterator on rows
TableDecorator tableDecorator = model.getTableDecorator();
Row previousRow = null;
Row currentRow = null;
Row nextRow = null;
Map previousRowValues = new HashMap(10);
Map currentRowValues = new HashMap(10);
Map nextRowValues = new HashMap(10);
while (nextRow != null || rowIterator.hasNext())
{
// The first pass
if (currentRow == null)
{
currentRow = rowIterator.next();
}
else
{
previousRow = currentRow;
currentRow = nextRow;
}
if (previousRow != null)
{
previousRowValues.putAll(currentRowValues);
}
if (!nextRowValues.isEmpty())
{
currentRowValues.putAll(nextRowValues);
}
// handle the first pass
else
{
ColumnIterator columnIterator = currentRow.getColumnIterator(model.getHeaderCellList());
// iterator on columns
if (log.isDebugEnabled())
{
log.debug(" creating ColumnIterator on " + model.getHeaderCellList());
}
while (columnIterator.hasNext())
{
Column column = columnIterator.nextColumn();
// Get the value to be displayed for the column
column.initialize();
CellStruct struct = new CellStruct(column, column.getChoppedAndLinkedValue());
currentRowValues.put(new Integer(column.getHeaderCell().getColumnNumber()), struct);
}
}
nextRowValues.clear();
// Populate the next row values
nextRow = rowIterator.hasNext() ? rowIterator.next() : null;
if (nextRow != null)
{
ColumnIterator columnIterator = nextRow.getColumnIterator(model.getHeaderCellList());
// iterator on columns
if (log.isDebugEnabled())
{
log.debug(" creating ColumnIterator on " + model.getHeaderCellList());
}
while (columnIterator.hasNext())
{
Column column = columnIterator.nextColumn();
column.initialize();
// Get the value to be displayed for the column
CellStruct struct = new CellStruct(column, column.getChoppedAndLinkedValue());
nextRowValues.put(new Integer(column.getHeaderCell().getColumnNumber()), struct);
}
}
// now we are going to create the current row; reset the decorator to the current row
if (tableDecorator != null)
{
tableDecorator.initRow(currentRow.getObject(), currentRow.getRowNumber(), currentRow.getRowNumber()
+ rowIterator.getPageOffset());
}
Iterator headerCellsIter = model.getHeaderCellList().iterator();
ArrayList structsForRow = new ArrayList(model.getHeaderCellList().size());
lowestEndedGroup = NO_RESET_GROUP;
lowestStartedGroup = NO_RESET_GROUP;
while (headerCellsIter.hasNext())
{
HeaderCell header = (HeaderCell) headerCellsIter.next();
// Get the value to be displayed for the column
CellStruct struct = (CellStruct) currentRowValues.get(new Integer(header.getColumnNumber()));
struct.decoratedValue = struct.bodyValue;
// Check and see if there is a grouping transition. If there is, then notify the decorator
if (header.getGroup() != -1)
{
CellStruct prior = (CellStruct) previousRowValues.get(new Integer(header.getColumnNumber()));
CellStruct next = (CellStruct) nextRowValues.get(new Integer(header.getColumnNumber()));
// Why npe?
String priorBodyValue = prior != null ? prior.bodyValue : null;
String nextBodyValue = next != null ? next.bodyValue : null;
short groupingValue = groupColumns(struct.bodyValue,
priorBodyValue, nextBodyValue, header.getGroup());
if (tableDecorator != null)
{
switch (groupingValue)
{
case GROUP_START :
tableDecorator.startOfGroup(struct.bodyValue, header.getGroup());
break;
case GROUP_END :
tableDecorator.endOfGroup(struct.bodyValue, header.getGroup());
break;
case GROUP_START_AND_END :
tableDecorator.startOfGroup(struct.bodyValue, header.getGroup());
tableDecorator.endOfGroup(struct.bodyValue, header.getGroup());
break;
default :
break;
}
}
if (tableDecorator != null)
{
struct.decoratedValue = tableDecorator.displayGroupedValue(struct.bodyValue,
groupingValue, header.getColumnNumber());
}
else if (groupingValue == GROUP_END || groupingValue == GROUP_NO_CHANGE)
{
struct.decoratedValue = TagConstants.EMPTY_STRING;