private TableRowInfoStructure validateRow(final TableSectionRenderBox section,
final RenderNode rowNode,
final TableRowInfoStructure prevInfoStruct)
{
final TableRowRenderBox rowBox = (TableRowRenderBox) rowNode;
final TableRowInfoStructure infoStruct =
rowBox.getRowInfoStructure();
// As we validate only closed table-rows (and as we do not allow changes once
// the rows are closed (except for adding auto-cells, of course, which is
// a necessary evil exception to the rule), we have to do this only once
// per row ..
if (infoStruct.isValidationDone())
{
return infoStruct;
}
RenderNode cellNode = rowBox.getFirstChild();
int cellPosition = 0;
while (cellNode != null)
{
if (cellNode instanceof TableCellRenderBox == false)
{
cellNode = cellNode.getNext();
continue;
}
final TableCellRenderBox cellBox = (TableCellRenderBox) cellNode;
// we got a cell. Now check our info-struct ..
if (cellPosition >= prevInfoStruct.getCellCount())
{
cellBox.setColumnIndex(cellPosition);
cellPosition = validateSafeCellPos(cellBox, infoStruct, cellPosition);
}
else
{
cellPosition = findCellPosition(cellPosition, prevInfoStruct, infoStruct);
// OK, so we have the insertation point. Lets add our cell there ..
final int colSpan = cellBox.getColSpan();
final int rowSpan = cellBox.getRowSpan();
final DataCell dataCell = new DataCell
(rowSpan, colSpan, cellBox.getInstanceId());
infoStruct.addCell(dataCell);
cellBox.setColumnIndex(cellPosition);
cellPosition += 1;
for (int i = 1; i < colSpan; i++)
{
// if there's a previous cell at the current position - check it
// maybe we have a conflicting instruction here
if (cellPosition < prevInfoStruct.getCellCount())
{
final TableCell prevCell = prevInfoStruct.getCellAt(cellPosition);
if (prevCell.getRowSpan() > 1)
{
// thats a conflict. Oh, no!
final ConflictingCell conflictingCell =
new ConflictingCell(dataCell, rowSpan, colSpan - i);
if (prevCell instanceof ConflictingCell)
{
// Oh, there's already a conflict? Coooool...
// (damn, users, fix your table definitions!)
final ConflictingCell prevConflictCell = (ConflictingCell) prevCell;
final int count = prevConflictCell.getConflictingCellCount();
for (int x = 0; x < count; x++)
{
final PlaceHolderCell phc = prevConflictCell.getConflictingCell(x);
if (phc.getRowSpan() > 1)
{
final PlaceHolderCell placeHolderCell =
new PlaceHolderCell(phc.getSourceCell(),
phc.getRowSpan() - 1,
phc.getColSpan());
conflictingCell.addConflictingCell(placeHolderCell);
}
}
}
else if (prevCell instanceof PlaceHolderCell)
{
final PlaceHolderCell prevPHCell = (PlaceHolderCell) prevCell;
// a new conflict ...
final PlaceHolderCell placeHolderCell =
new PlaceHolderCell(prevPHCell.getSourceCell(),
prevCell.getRowSpan() - 1,
prevCell.getColSpan());
conflictingCell.addConflictingCell(placeHolderCell);
}
else if (prevCell instanceof DataCell)
{
final PlaceHolderCell placeHolderCell =
new PlaceHolderCell((DataCell) prevCell,
prevCell.getRowSpan() - 1,
prevCell.getColSpan());
conflictingCell.addConflictingCell(placeHolderCell);
}
else
{
throw new IllegalStateException("Unexpected cell type.");
}
infoStruct.addCell(conflictingCell);
}
else
{
final PlaceHolderCell placeHolderCell =
new PlaceHolderCell(dataCell, rowSpan, colSpan - i);
// a safe position. No conflicts ..
infoStruct.addCell(placeHolderCell);
}
}
else
{
final PlaceHolderCell placeHolderCell =
new PlaceHolderCell(dataCell, rowSpan, colSpan - i);
// no cells means: no conflicts. Thats always the easiest thing
infoStruct.addCell(placeHolderCell);
}
cellPosition += 1;
}
}
cellNode = cellNode.getNext();
}
final TableRow row = new TableRow(rowBox.getBorder());
section.getRowModel().addRow(row);
infoStruct.setValidationDone(true);
return infoStruct;
}