state = state.commit();
continue;
}
final DefaultOutputFunction lm = (DefaultOutputFunction) outputFunction;
final Renderer renderer = lm.getRenderer();
pagebreakHandler.setReportState(state);
boolean assertExpectPagebreak = false;
if (isInRollBackMode)
{
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.
// Log.debug ("HERE: Found real pagebreak position. This might be the last state we process.");
assertExpectPagebreak = true;
renderer.addPagebreak(state.getProcessKey());
}
}
final Renderer.LayoutResult pagebreakEncountered = renderer.validatePages();
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());
}
fallBackState = realFallbackState;
pageEventCount = 0;
}
else
{
pageEventCount += 1;
}
}
}
}
if (pagebreakEncountered == Renderer.LayoutResult.LAYOUT_PAGEBREAK)
{
final ReportStateKey lastVisibleStateKey = renderer.getLastStateKey();
if (pagebreaksSupported &&
isInRollBackMode == false &&
renderer.isOpen() &&
lastVisibleStateKey != null)
{
if (lastVisibleStateKey.equals(nextStateKey) == false)
{
// Log.debug ("HERE: Encountered bad break, need to roll-back");
// 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(
"Print: Encountered bad break, need to roll-back: " + rollbackPageState);
AbstractReportProcessor.logger.debug(
"Print: : " + state.getProcessKey());
AbstractReportProcessor.logger.debug(
"Print: : " + restoreStateProcessKey);
}
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;
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("Print: Encountered on-going break " + lastVisibleStateKey);
}
}
}
else
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
AbstractReportProcessor.logger.debug(
"Print: Encountered a good break or a roll-back break: " + isInRollBackMode);
AbstractReportProcessor.logger.debug(
"Print: : " + state.getProcessKey());
}
}
if (pagebreaksSupported == 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(), performOutput) == false)
{
throw new IllegalStateException("This must not be.");
}
if (isPagebreaksSupported() && renderer.isPendingPageHack() &&
renderer.isCurrentPageEmpty() == false && renderer.isPageStartPending() == false)
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Print: Delaying next event to allow pending pages to be processed: " + state.getProcessKey());
}
state = PendingPagesHandler.create(state);
}
else if (isPagebreaksSupported())
{
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Print: Adding RestartOnNewPageHandler to open Page in time: " + state.getProcessKey());
}
state = RestartOnNewPageHandler.create(state.commit());
}
else
{
state = state.commit();
}
if (renderer.isOpen())
{
// No need to create a copy here. It is part of the contract that the resulting page state must be
// cloned before it can be used again. The only place where it is used is this method, so we can
// be pretty sure that this contract is valid.
return new PageState(state, outputProcessor.getPageCursor());
}
}
else
{
if (pagebreaksSupported == 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 (pageEventCount == 0 && isInRollBackMode == false &&
pagebreakEncountered == Renderer.LayoutResult.LAYOUT_NO_PAGEBREAK)
{
renderer.processIncrementalUpdate(performOutput);
}
state = state.commit();
// Expected a pagebreak now, but did not encounter one.
// 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.
// Log.debug ("HERE: Ups, Found real pagebreak position. but where is my break?");
// //renderer.addPagebreak(state.getProcessKey());
// }
if (pagebreaksSupported && fallBackState != restoreState)
{
final DefaultOutputFunction commitableOutputFunction =
(DefaultOutputFunction) state.getLayoutProcess().getOutputFunction();
final Renderer commitableRenderer = commitableOutputFunction.getRenderer();
commitableRenderer.applyRollbackInformation();
}
}
}
// We should never reach this point, if this function has been called by the PageStateList.