sw.start();
final boolean failOnError = isStrictErrorHandling(getReport().getReportConfiguration());
final ReportProcessingErrorHandler errorHandler = new CollectingReportErrorHandler();
final DefaultLayoutPagebreakHandler pagebreakHandler = new DefaultLayoutPagebreakHandler();
final ProcessState initialReportState = startState.deriveForStorage();
final PageState initialPageState = new PageState(initialReportState, outputProcessor.getPageCursor());
pageStates.add(initialPageState);
final ReportProgressEvent repaginationState = new ReportProgressEvent(this);
// inner loop: process the complete report, calculate the function values
// for the current level. Higher level functions are not available in the
// dataRow.
final int eventTrigger;
if (maxRows <= 0)
{
eventTrigger = Math.max(maxRows / MAX_EVENTS_PER_RUN, MIN_ROWS_PER_EVENT);
}
else
{
eventTrigger = Math.min(maxRows, Math.max(maxRows / MAX_EVENTS_PER_RUN, MIN_ROWS_PER_EVENT));
}
ProcessState state = startState.deriveForStorage();
state.setErrorHandler(errorHandler);
validate(state);
final OutputProcessorMetaData metaData =
state.getFlowController().getReportContext().getOutputProcessorMetaData();
pagebreaksSupported = metaData.isFeatureSupported(OutputProcessorFeature.PAGEBREAKS);
int pageEventCount = 0;
// First and last derive of a page must be a storage derivate - this clones everything and does
// not rely on the more complicated transactional layouting ..
ProcessState fallBackState = pagebreaksSupported ? state.deriveForPagebreak() : null;
ProcessState globalState = pagebreaksSupported ? state.deriveForStorage() : null;
ReportStateKey rollbackPageState = null;
boolean isInRollBackMode = false;
int eventCount = 0;
int lastRow = -1;
while (!state.isFinish())
{
int logPageCount = outputProcessor.getLogicalPageCount();
int physPageCount = outputProcessor.getPhysicalPageCount();
checkInterrupted();
if (lastRow != state.getCurrentRow())
{
lastRow = state.getCurrentRow();
if (eventCount == 0)
{
if (isPagebreaksSupported() && fallBackState != null)
{
repaginationState.reuse(ReportProgressEvent.PAGINATING, fallBackState, calculatePageCount(fallBackState));
}
else
{
repaginationState.reuse(ReportProgressEvent.PAGINATING, state, calculatePageCount(state));
}
fireStateUpdate(repaginationState);
eventCount += 1;
}
else
{
if (eventCount == eventTrigger)
{
eventCount = 0;
}
else
{
eventCount += 1;
}
}
}
// Do not try to layout on a artificial state. Those states are not valid on
// generating page events and cannot be trusted.
ProcessState realFallbackState = fallBackState;
final ProcessState restoreState;
if (pagebreaksSupported && state.isArtifcialState() == false)
{
restoreState = fallBackState;
if (isInRollBackMode == false)
{
if (pageEventCount >= AbstractReportProcessor.COMMIT_RATE)
{
final OutputFunction outputFunction = state.getLayoutProcess().getOutputFunction();
if (outputFunction.createRollbackInformation())
{
realFallbackState = state.deriveForPagebreak();
if (AbstractReportProcessor.SHOW_ROLLBACKS)
{
logger.debug("Paginate: Try to generate new fallback state after commit count reached: " + state.getProcessKey());
}
validate(state);
}
else
{
realFallbackState = null;
}
}
}
}
else
{
restoreState = null;
}
final ProcessState nextState = state.advance();
state.setErrorHandler(IgnoreEverythingReportErrorHandler.INSTANCE);
state = nextState;
validate(state);
final ReportStateKey nextStateKey = state.getProcessKey();