}
continue;
}
final DefaultOutputFunction lm = (DefaultOutputFunction) outputFunction;
final Renderer renderer = lm.getRenderer();
pagebreakHandler.setReportState(state);
boolean assertExpectPagebreak = false;
if (isInRollBackMode)
{
// todo: Could be that we have to use the other key here..
// was: state.getProcessKey()
if (nextStateKey.equals(rollbackPageState))
{
// reached the border case. We have to insert a manual pagebreak here or at least
// we have to force the renderer to end the page right now.
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug(
"Paginate: Found real pagebreak position. This might be the last state we process: " + rollbackPageState);
AbstractReportProcessor.logger.debug(
"Paginate: : " + state.getProcessKey());
if (restoreState != null)
{
AbstractReportProcessor.logger.debug(
"Paginate: : " + restoreState.getProcessKey());
}
AbstractReportProcessor.logger.debug(
"Paginate: (Handler) : " + state.getAdvanceHandler());
}
assertExpectPagebreak = true;
renderer.addPagebreak(state.getProcessKey());
}
}
final Renderer.LayoutResult pagebreakEncountered = renderer.validatePages();
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug("Validate Page returned " + pagebreakEncountered);
}
if (assertExpectPagebreak == true && pagebreakEncountered != Renderer.LayoutResult.LAYOUT_PAGEBREAK)
{
if (SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug("Paginate: Missed the pagebreak. This smells fishy!");
}
}
if (pagebreakEncountered != Renderer.LayoutResult.LAYOUT_UNVALIDATABLE)
{
if (pagebreaksSupported && state.isArtifcialState() == false)
{
if (isInRollBackMode == false)
{
if (pageEventCount >= AbstractReportProcessor.COMMIT_RATE)
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Paginate: Try to apply new fallback state after commit count reached: " + state.getProcessKey());
logger.debug("Paginate: : " + renderer.getLastStateKey());
}
fallBackState = realFallbackState;
pageEventCount = 0;
}
else
{
pageEventCount += 1;
}
}
}
}
if (pagebreakEncountered == Renderer.LayoutResult.LAYOUT_PAGEBREAK)
{
final ReportStateKey lastVisibleStateKey = renderer.getLastStateKey();
if (isPagebreaksSupported() &&
isInRollBackMode == false &&
lastVisibleStateKey != null &&
renderer.isOpen())
{
if (lastVisibleStateKey.equals(nextStateKey) == false)
{
// Roll back to the last known to be good position and process the states up to, but not
// including the current state. This way, we can fire the page-events *before* this band
// gets printed.
rollbackPageState = lastVisibleStateKey;
final ReportStateKey restoreStateProcessKey = restoreState.getProcessKey();
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug(
"Paginate: Encountered bad break, need to roll-back: " + rollbackPageState);
AbstractReportProcessor.logger.debug(
"Paginate: Next StateKey : " + state.getProcessKey());
AbstractReportProcessor.logger.debug(
"Paginate: Restored Key : " + restoreStateProcessKey);
AbstractReportProcessor.logger.debug(
"Paginate: Position in event chain : " + restoreState.getSequenceCounter());
}
if (lastVisibleStateKey.getSequenceCounter() < restoreStateProcessKey.getSequenceCounter())
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug(
"Print: Fall back to start of page : " + restoreStateProcessKey);
}
state = globalState.deriveForPagebreak();
}
else
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug(
"Print: Fall back to save-state : " + restoreStateProcessKey);
}
state = restoreState.deriveForPagebreak();
}
final DefaultOutputFunction rollbackOutputFunction = (DefaultOutputFunction) state.getLayoutProcess().getOutputFunction();
final Renderer rollbackRenderer = rollbackOutputFunction.getRenderer();
rollbackRenderer.rollback();
validate(state);
isInRollBackMode = true;
fallBackState = null; // there is no way we can fall-back inside a roll-back ..
continue;
}
else
{
// The current state printed content partially on the now finished page and there is more
// content on the currently open page. This is a in-between pagebreak, we invoke a pagebreak
// after this state has been processed.
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug("Paginate: Encountered on-going break " + lastVisibleStateKey);
}
}
}
else
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
if (isInRollBackMode)
{
if (assertExpectPagebreak == false)
{
if (nextStateKey.equals(rollbackPageState) == false)
{
AbstractReportProcessor.logger.debug("X1: " + nextStateKey);
AbstractReportProcessor.logger.debug("X2: " + rollbackPageState);
}
}
AbstractReportProcessor.logger.debug("Paginate: Encountered a roll-back break: " + isInRollBackMode);
}
else
{
AbstractReportProcessor.logger.debug("Paginate: Encountered a good break: " + isInRollBackMode);
}
AbstractReportProcessor.logger.debug
("Paginate: : " + state.getProcessKey());
}
isInRollBackMode = false;
rollbackPageState = null;
}
if (isPagebreaksSupported() == false)
{
// The commit causes all closed-nodes to become finishable. This allows the process-page
// and the incremental-update methods to remove the nodes. For non-streaming targets (where
// pagebreaks are possible) the commit state is managed manually
renderer.applyAutoCommit();
}
if (renderer.processPage(pagebreakHandler, state.getProcessKey(), true) == false)
{
throw new IllegalStateException
("This cannot be. If the validation said we get a new page, how can we now get lost here");
}
if (isPagebreaksSupported() && renderer.isPendingPageHack() &&
renderer.isCurrentPageEmpty() == false && renderer.isPageStartPending() == false)
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Paginate: Delaying next event to allow pending pages to be processed: " + state.getProcessKey());
}
state = PendingPagesHandler.create(state);
}
else if (isPagebreaksSupported())
{
state = RestartOnNewPageHandler.create(state.commit());
}
else
{
state = state.commit();
}
// can continue safely ..
final int newLogPageCount = outputProcessor.getLogicalPageCount();
final int newPhysPageCount = outputProcessor.getPhysicalPageCount();
final int result = pageStates.size() - 1;
for (; physPageCount < newPhysPageCount; physPageCount++)
{
physicalMapping.add(result);
}
for (; logPageCount < newLogPageCount; logPageCount++)
{
logicalMapping.add(result);
}
if (state.isFinish() == false)
{
// A pagebreak has occured ...
// We add all but the last state ..
final PageState pageState = new PageState(state, outputProcessor.getPageCursor());
pageStates.add(pageState);
}
if (isPagebreaksSupported())
{
fallBackState = state.deriveForPagebreak();
globalState = state.deriveForStorage();
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Paginate: Generating new fallback state after pagebreak found: " + state.getProcessKey());
}
pageEventCount = 0;
eventCount = 0;
}
}
else
{
if (isPagebreaksSupported() == false)
{
renderer.applyAutoCommit();
}
// PageEventCount is zero on streaming exports and zero after a new rollback event is created.
if (pageEventCount == 0 && isInRollBackMode == false &&
pagebreakEncountered == Renderer.LayoutResult.LAYOUT_NO_PAGEBREAK)
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Paginate: Perform incremental update: " + state.getProcessKey());
}
renderer.processIncrementalUpdate(false);
}
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Paginate: Commit: " + state.getProcessKey() + " " + state.getAdvanceHandler());
}
state = state.commit();
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Paginate: Post Commit: " + state.getProcessKey() + " " + state.getAdvanceHandler());
}
if (pagebreaksSupported && fallBackState != restoreState)
{
final DefaultOutputFunction commitableOutputFunction =
(DefaultOutputFunction) state.getLayoutProcess().getOutputFunction();
final Renderer commitableRenderer = commitableOutputFunction.getRenderer();
commitableRenderer.applyRollbackInformation();
}
}
}
return initialReportState;