/* * This is eMonocot, a global online biodiversity information resource. * * Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford * * eMonocot is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * The complete text of the GNU Affero General Public License is in the source repository as the file * ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>. */ package net.sf.jasperreports.engine.fill; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Random; import net.sf.jasperreports.engine.DefaultJasperReportsContext; import net.sf.jasperreports.engine.JRBand; import net.sf.jasperreports.engine.JRDataSource; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.JRExpression; import net.sf.jasperreports.engine.JRGroup; import net.sf.jasperreports.engine.JRParameter; import net.sf.jasperreports.engine.JRPrintElement; import net.sf.jasperreports.engine.JRRuntimeException; import net.sf.jasperreports.engine.JasperExportManager; import net.sf.jasperreports.engine.JasperReport; import net.sf.jasperreports.engine.JasperReportsContext; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.type.FooterPositionEnum; import net.sf.jasperreports.engine.type.IncrementTypeEnum; import net.sf.jasperreports.engine.type.ResetTypeEnum; import net.sf.jasperreports.engine.type.RunDirectionEnum; import net.sf.jasperreports.engine.util.JRDataUtils; import net.sf.jasperreports.engine.util.LinkedMap; import net.sf.jasperreports.engine.util.LocalJasperReportsContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.StepExecutionListener; import org.springframework.batch.item.ItemWriter; import org.springframework.core.io.Resource; /** * @author jk00kg * * A Simple Report Writer that currently supports a subset of report functionality. Specifically, report templates that * require summary and aggregate figures have not been tested within the batch context. * * The code sits in this package as protected scope methods & objects are required and much of the JasperReportFiller * functionality is copied from {@link JRVerticalFiller}. * @author Teodor Danciu (teodord@users.sourceforge.net) * @version $Id: JRVerticalFiller.java 5687 2012-10-01 14:18:01Z lucianc $ * */ public class JRVerticalReportWriter<T> extends JRBaseFiller implements ItemWriter<T>, StepExecutionListener { /** * @throws Exception * */ public JRVerticalReportWriter(JasperReport jasperReport) throws Exception { this(DefaultJasperReportsContext.getInstance(), jasperReport); } /** * */ private Logger logger = LoggerFactory.getLogger(JRVerticalReportWriter.class); /** * Records whether there is data */ private boolean hadData = false; /** * */ private Resource outputResouce; /** * By default an empty map of parameters used by JasperReports */ private Map<String, Object> parameterValues = new HashMap<String, Object>(); /** * */ private String defaultOutputDir; /** * @return the defaultOutputDir */ public String getDefaultOutputDir() { return defaultOutputDir; } /** * @param defaultOutputDir the defaultOutputDir to set */ public void setDefaultOutputDir(String defaultOutputDir) { this.defaultOutputDir = defaultOutputDir; } /** * @return the outputResouce */ public Resource getOutputResouce() { return outputResouce; } /** * @param outputResouce the outputResouce to set */ public void setOutputResouce(Resource outputResouce) { this.outputResouce = outputResouce; } /** * @return the parameterValues */ public Map<String, Object> getParameterValues() { return parameterValues; } /** * @param parameterValues the parameterValues to set */ public void setParameterValues(Map<String, Object> parameterValues) { this.parameterValues = parameterValues; } /* (non-Javadoc) * @see org.springframework.batch.core.StepExecutionListener#beforeStep(org.springframework.batch.core.StepExecution) */ @Override public void beforeStep(StepExecution stepExecution) { hadData = false; // Functionality from JRBaseFiller, other 'pre-write/pre-fill functions can only happen once *some* // data has been loaded and is therefore called in this.write() baseInit(); } /* (non-Javadoc) * @see org.springframework.batch.core.StepExecutionListener#afterStep(org.springframework.batch.core.StepExecution) */ @Override public ExitStatus afterStep(StepExecution stepExecution) { // fill/write footers String fileName = null; try { if (hadData) { fillReportEnd(); } else { //TODO Add from 'else' block. We don't expect to hit this code; possibly if attempting to download data // that doesn't contain a license } //Then export and return appropriate execution status if(outputResouce != null) { fileName = outputResouce.getFile().getCanonicalPath(); } else { fileName = defaultOutputDir + "/checklist" + Math.abs((new Random()).nextLong()) + ".pdf"; } JasperExportManager.exportReportToPdfFile(jasperPrint, fileName); } catch (JRException e) { logger.error("Unable to export report to " + fileName, e); return ExitStatus.FAILED; } catch (IOException e) { logger.error("Unable to write to file" + fileName + ". There was probably a problem trying to use the file " + outputResouce, e); } baseClose(); return ExitStatus.COMPLETED; } /* (non-Javadoc) * @see org.springframework.batch.item.ItemWriter#write(java.util.List) */ @Override public void write(List<? extends T> items) throws Exception { //To make Filler compatible with chunk-oriented processing: //Update the dataset now instead of beginning writing as we don't operate on whole datasets. JRDataSource ds = new JRBeanCollectionDataSource(items); getMainDataset().getParametersMap().get(JRParameter.REPORT_DATA_SOURCE).setValue(ds); getMainDataset().initDatasource(); //Then use tweeked JasperReports code if(!hadData) {//On the first chunk try { if(next()) { hadData = true; //Alternative to calling next() which isn't idempotent. fillReportStart(); } } catch (JRException e) { logger.error("Unable to fill headers of file"); } } setLastPageFooter(false); //Fill it in if (hadData) { while (next()) { fillReportContent(); } } else { logger.debug("Fill " + fillerId + ": no data"); switch (whenNoDataType) { case ALL_SECTIONS_NO_DETAIL : { logger.debug("Fill " + fillerId + ": all sections"); scriptlet.callBeforeReportInit(); calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT); scriptlet.callAfterReportInit(); printPage = newPage(); addPage(printPage); setFirstColumn(); offsetY = topMargin; fillBackground(); fillTitle(); fillPageHeader(JRExpression.EVALUATION_DEFAULT); fillColumnHeader(JRExpression.EVALUATION_DEFAULT); fillGroupHeaders(true); fillGroupFooters(true); fillSummary(); break; } case BLANK_PAGE : { logger.debug("Fill " + fillerId + ": blank page"); printPage = newPage(); addPage(printPage); break; } case NO_DATA_SECTION: { logger.debug("Fill " + fillerId + ": all sections"); scriptlet.callBeforeReportInit(); calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT); scriptlet.callAfterReportInit(); printPage = newPage(); addPage(printPage); setFirstColumn(); offsetY = topMargin; fillBackground(); fillNoData(); break; } case NO_PAGES : default : { logger.debug("Fill " + fillerId + ": no pages"); } } } if (isSubreport()) { //if ( // columnIndex == 0 || // (columnIndex > 0 && printPageStretchHeight < offsetY + bottomMargin) // ) //{ printPageStretchHeight = offsetY + bottomMargin; //} } if (fillContext.isIgnorePagination()) { jasperPrint.setPageHeight(offsetY + bottomMargin); } } //Unmodified methods from jasperreports 5.0.0 JRVerticalFiller /** * */ protected JRVerticalReportWriter( JasperReportsContext jasperReportsContext, JasperReport jasperReport ) throws JRException { this(jasperReportsContext, jasperReport, null, null); } /** * */ protected JRVerticalReportWriter( JasperReportsContext jasperReportsContext, JasperReport jasperReport, JRFillSubreport parentElement ) throws JRException { super(jasperReportsContext, jasperReport, null, parentElement); setPageHeight(pageHeight); } /** * */ protected JRVerticalReportWriter( JasperReportsContext jasperReportsContext, JasperReport jasperReport, DatasetExpressionEvaluator evaluator, JRFillSubreport parentElement ) throws JRException { super(jasperReportsContext, jasperReport, evaluator, parentElement); setPageHeight(pageHeight); } /** * */ protected JRVerticalReportWriter( JasperReportsContext jasperReportsContext, JasperReport jasperReport, JREvaluator evaluator, JRFillSubreport parentElement ) throws JRException { this(jasperReportsContext, jasperReport, (DatasetExpressionEvaluator) evaluator, parentElement); } /** * */ protected void setPageHeight(int pageHeight) { this.pageHeight = pageHeight; columnFooterOffsetY = pageHeight - bottomMargin; if (pageFooter != null) { columnFooterOffsetY -= pageFooter.getHeight(); } if (columnFooter != null) { columnFooterOffsetY -= columnFooter.getHeight(); } lastPageColumnFooterOffsetY = pageHeight - bottomMargin; if (lastPageFooter != null)//FIXMENOW testing with null is awkward since bands can never be null, but rather equal to missingFillBand { lastPageColumnFooterOffsetY -= lastPageFooter.getHeight(); } if (columnFooter != null) { lastPageColumnFooterOffsetY -= columnFooter.getHeight(); } logger.debug("Filler " + fillerId + " - pageHeight: " + pageHeight + ", columnFooterOffsetY: " + columnFooterOffsetY + ", lastPageColumnFooterOffsetY: " + lastPageColumnFooterOffsetY); } /** * */ protected synchronized void fillReport() throws JRException { setLastPageFooter(false); if (next()) { fillReportStart(); while (next()) { fillReportContent(); } fillReportEnd(); } else { logger.debug("Fill " + fillerId + ": no data"); switch (whenNoDataType) { case ALL_SECTIONS_NO_DETAIL : { logger.debug("Fill " + fillerId + ": all sections"); scriptlet.callBeforeReportInit(); calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT); scriptlet.callAfterReportInit(); printPage = newPage(); addPage(printPage); setFirstColumn(); offsetY = topMargin; fillBackground(); fillTitle(); fillPageHeader(JRExpression.EVALUATION_DEFAULT); fillColumnHeader(JRExpression.EVALUATION_DEFAULT); fillGroupHeaders(true); fillGroupFooters(true); fillSummary(); break; } case BLANK_PAGE : { logger.debug("Fill " + fillerId + ": blank page"); printPage = newPage(); addPage(printPage); break; } case NO_DATA_SECTION: { logger.debug("Fill " + fillerId + ": all sections"); scriptlet.callBeforeReportInit(); calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT); scriptlet.callAfterReportInit(); printPage = newPage(); addPage(printPage); setFirstColumn(); offsetY = topMargin; fillBackground(); fillNoData(); break; } case NO_PAGES : default : { logger.debug("Fill " + fillerId + ": no pages"); } } } if (isSubreport()) { //if ( // columnIndex == 0 || // (columnIndex > 0 && printPageStretchHeight < offsetY + bottomMargin) // ) //{ printPageStretchHeight = offsetY + bottomMargin; //} } if (fillContext.isIgnorePagination()) { jasperPrint.setPageHeight(offsetY + bottomMargin); } } /** * */ private void fillReportStart() throws JRException { scriptlet.callBeforeReportInit(); calculator.initializeVariables(ResetTypeEnum.REPORT, IncrementTypeEnum.REPORT); scriptlet.callAfterReportInit(); printPage = newPage(); addPage(printPage); setFirstColumn(); offsetY = topMargin; fillBackground(); fillTitle(); fillPageHeader(JRExpression.EVALUATION_DEFAULT); fillColumnHeader(JRExpression.EVALUATION_DEFAULT); fillGroupHeaders(true); fillDetail(); } /** * */ private void fillReportContent() throws JRException { calculator.estimateGroupRuptures(); fillGroupFooters(false); resolveGroupBoundElements(JRExpression.EVALUATION_OLD, false); scriptlet.callBeforeGroupInit(); calculator.initializeVariables(ResetTypeEnum.GROUP, IncrementTypeEnum.GROUP); scriptlet.callAfterGroupInit(); fillGroupHeaders(false); fillDetail(); } /** * */ private void fillReportEnd() throws JRException { fillGroupFooters(true); fillSummary(); } /** * */ private void fillTitle() throws JRException { logger.debug("Fill " + fillerId + ": title at " + offsetY); title.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (title.isToPrint()) { while ( title.getBreakHeight() > pageHeight - bottomMargin - offsetY ) { addPage(false); } title.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = title.fill(pageHeight - bottomMargin - offsetY); if (title.willOverflow() && title.isSplitPrevented() && isSubreport()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = title.refill(pageHeight - bottomMargin - offsetY); } fillBand(printBand); offsetY += printBand.getHeight(); while (title.willOverflow()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = title.fill(pageHeight - bottomMargin - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } resolveBandBoundElements(title, JRExpression.EVALUATION_DEFAULT); if (isTitleNewPage) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); } } } /** * */ private void fillPageHeader(byte evaluation) throws JRException { logger.debug("Fill " + fillerId + ": page header at " + offsetY); setNewPageColumnInBands(); pageHeader.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (pageHeader.isToPrint()) { int reattempts = getMasterColumnCount(); if (isCreatingNewPage) { --reattempts; } boolean filled = fillBandNoOverflow(pageHeader, evaluation); for (int i = 0; !filled && i < reattempts; ++i) { resolveGroupBoundElements(evaluation, false); resolveColumnBoundElements(evaluation); resolvePageBoundElements(evaluation); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); filled = fillBandNoOverflow(pageHeader, evaluation); } if (!filled) { throw new JRRuntimeException("Infinite loop creating new page due to page header overflow."); } } columnHeaderOffsetY = offsetY; isNewPage = true; isFirstPageBand = true; } private boolean fillBandNoOverflow(JRFillBand band, byte evaluation) throws JRException { int availableHeight = columnFooterOffsetY - offsetY; boolean overflow = availableHeight < band.getHeight(); if (!overflow) { band.evaluate(evaluation); JRPrintBand printBand = band.fill(availableHeight); overflow = band.willOverflow(); if (overflow) { band.rewind(); } else { fillBand(printBand); offsetY += printBand.getHeight(); resolveBandBoundElements(band, evaluation); } } return !overflow; } /** * */ private void fillColumnHeader(byte evaluation) throws JRException { logger.debug("Fill " + fillerId + ": column header at " + offsetY); setNewPageColumnInBands(); columnHeader.evaluatePrintWhenExpression(evaluation); if (columnHeader.isToPrint()) { int reattempts = getMasterColumnCount(); if (isCreatingNewPage) { --reattempts; } setOffsetX(); boolean filled = fillBandNoOverflow(columnHeader, evaluation); for (int i = 0; !filled && i < reattempts; ++i) { while (columnIndex < columnCount - 1) { resolveGroupBoundElements(evaluation, false); resolveColumnBoundElements(evaluation); scriptlet.callBeforeColumnInit(); calculator.initializeVariables(ResetTypeEnum.COLUMN, IncrementTypeEnum.COLUMN); scriptlet.callAfterColumnInit(); columnIndex += 1; setOffsetX(); offsetY = columnHeaderOffsetY; setColumnNumberVar(); } fillPageFooter(evaluation); resolveGroupBoundElements(evaluation, false); resolveColumnBoundElements(evaluation); resolvePageBoundElements(evaluation); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(evaluation); filled = fillBandNoOverflow(columnHeader, evaluation); } if (!filled) { throw new JRRuntimeException("Infinite loop creating new page due to column header overflow."); } } isNewColumn = true; isFirstColumnBand = true; } /** * */ private void fillGroupHeaders(boolean isFillAll) throws JRException { if (groups != null && groups.length > 0) { for(int i = 0; i < groups.length; i++) { JRFillGroup group = groups[i]; if(isFillAll || group.hasChanged()) { SavePoint newSavePoint = fillGroupHeader(group); // fillGroupHeader never returns null, because we need a save point // regardless of the group header printing or not newSavePoint.groupIndex = i; if (keepTogetherSavePoint == null && group.isKeepTogether()) { keepTogetherSavePoint = newSavePoint; } } } } } /** * */ private SavePoint fillGroupHeader(JRFillGroup group) throws JRException { SavePoint savePoint = null; JRFillSection groupHeaderSection = (JRFillSection)group.getGroupHeaderSection(); logger.debug("Fill " + fillerId + ": " + group.getName() + " header at " + offsetY); byte evalPrevPage = (group.isTopLevelChange()?JRExpression.EVALUATION_OLD:JRExpression.EVALUATION_DEFAULT); if ( (group.isStartNewPage() || group.isResetPageNumber()) && !isNewPage ) { fillPageBreak( group.isResetPageNumber(), evalPrevPage, JRExpression.EVALUATION_DEFAULT, true ); } else if ( group.isStartNewColumn() && !isNewColumn ) { fillColumnBreak( evalPrevPage, JRExpression.EVALUATION_DEFAULT ); } JRFillBand[] groupHeaderBands = groupHeaderSection.getFillBands(); for(int i = 0; i < groupHeaderBands.length; i++) { JRFillBand groupHeaderBand = groupHeaderBands[i]; groupHeaderBand.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (groupHeaderBand.isToPrint()) { while ( groupHeaderBand.getBreakHeight() > columnFooterOffsetY - offsetY || group.getMinHeightToStartNewPage() > columnFooterOffsetY - offsetY ) { fillColumnBreak( evalPrevPage, JRExpression.EVALUATION_DEFAULT ); } } if (i == 0) { setNewGroupInBands(group); group.setFooterPrinted(false); } if (groupHeaderBand.isToPrint()) { SavePoint newSavePoint = fillColumnBand(groupHeaderBand, JRExpression.EVALUATION_DEFAULT); savePoint = advanceSavePoint(savePoint, newSavePoint); isFirstPageBand = false; isFirstColumnBand = false; } } group.setHeaderPrinted(true); isNewGroup = true; if (savePoint == null) { // fillGroupHeader never returns null, because we need a save point // regardless of the group header printing or not savePoint = new SavePoint( getCurrentPage(), columnIndex, isNewPage, isNewColumn, offsetY ); } return savePoint; } /** * */ private void fillGroupHeadersReprint(byte evaluation) throws JRException { if (groups != null && groups.length > 0) { for(int i = 0; i < groups.length; i++) { fillGroupHeaderReprint(groups[i], evaluation); } } } /** * */ private void fillGroupHeaderReprint(JRFillGroup group, byte evaluation) throws JRException { if ( group.isReprintHeaderOnEachPage() && (!group.hasChanged() || (group.hasChanged() && group.isHeaderPrinted())) ) { JRFillSection groupHeaderSection = (JRFillSection)group.getGroupHeaderSection(); JRFillBand[] groupHeaderBands = groupHeaderSection.getFillBands(); for(int i = 0; i < groupHeaderBands.length; i++) { JRFillBand groupHeaderBand = groupHeaderBands[i]; groupHeaderBand.evaluatePrintWhenExpression(evaluation); if (groupHeaderBand.isToPrint()) { while ( groupHeaderBand.getBreakHeight() > columnFooterOffsetY - offsetY || group.getMinHeightToStartNewPage() > columnFooterOffsetY - offsetY ) { fillColumnBreak(evaluation, evaluation); } fillColumnBand(groupHeaderBand, evaluation); isFirstPageBand = false; isFirstColumnBand = false; } } } } /** * */ private void fillDetail() throws JRException { logger.debug("Fill " + fillerId + ": detail at " + offsetY); if (!detailSection.areAllPrintWhenExpressionsNull()) { calculator.estimateVariables(); } JRFillBand[] detailBands = detailSection.getFillBands(); for(int i = 0; i < detailBands.length; i++) { JRFillBand detailBand = detailBands[i]; detailBand.evaluatePrintWhenExpression(JRExpression.EVALUATION_ESTIMATED); if (detailBand.isToPrint()) { while ( detailBand.getBreakHeight() > columnFooterOffsetY - offsetY ) { byte evalPrevPage = (isNewGroup?JRExpression.EVALUATION_DEFAULT:JRExpression.EVALUATION_OLD); fillColumnBreak( evalPrevPage, JRExpression.EVALUATION_DEFAULT ); } break; } } scriptlet.callBeforeDetailEval(); calculator.calculateVariables(); scriptlet.callAfterDetailEval(); if (detailBands != null) { for(int i = 0; i < detailBands.length; i++) { JRFillBand detailBand = detailBands[i]; detailBand.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (detailBand.isToPrint()) { fillColumnBand(detailBand, JRExpression.EVALUATION_DEFAULT); isFirstPageBand = false; isFirstColumnBand = false; } } } isNewPage = false; isNewColumn = false; isNewGroup = false; } /** * */ private void fillGroupFooters(boolean isFillAll) throws JRException { if (groups != null && groups.length > 0) { SavePoint savePoint = null; byte evaluation = (isFillAll)?JRExpression.EVALUATION_DEFAULT:JRExpression.EVALUATION_OLD; for(int i = groups.length - 1; i >= 0; i--) { JRFillGroup group = groups[i]; if (isFillAll || group.hasChanged()) { SavePoint newSavePoint = fillGroupFooter(group, evaluation); // fillGroupFooter might return null, because if the group footer does not print, // its footer position is completely irrelevant if (newSavePoint != null) { switch (group.getFooterPositionValue()) { case STACK_AT_BOTTOM: { savePoint = advanceSavePoint(savePoint, newSavePoint); if (savePoint != null) { savePoint.footerPosition = FooterPositionEnum.STACK_AT_BOTTOM; } break; } case FORCE_AT_BOTTOM: { savePoint = advanceSavePoint(savePoint, newSavePoint); if (savePoint != null) { savePoint.moveSavePointContent(); offsetY = columnFooterOffsetY; } savePoint = null; break; } case COLLATE_AT_BOTTOM: { savePoint = advanceSavePoint(savePoint, newSavePoint); break; } case NORMAL: default: { if (savePoint != null) { //only "StackAtBottom" and "CollateAtBottom" save points could get here // check to see if the new save point is on the same page/column as the previous one if ( savePoint.page == newSavePoint.page && savePoint.columnIndex == newSavePoint.columnIndex ) { // if the new save point is on the same page/column, // we just move the marker on the existing save point, // but only if was a "StackAtBottom" one if (savePoint.footerPosition == FooterPositionEnum.STACK_AT_BOTTOM) { savePoint.saveHeightOffset(newSavePoint.heightOffset); } else { // we cancel the "CollateAtBottom" save point savePoint = null; } } else { // page/column break occurred, so the move operation // must be performed on the previous save point, regardless // whether it was a "StackAtBottom" or a "CollateAtBottom" savePoint.moveSavePointContent(); savePoint = null; } } else { // only "ForceAtBottom" save points could get here, but they are already null savePoint = null; } } } } // regardless of whether the fillGroupFooter returned a save point or not // (footer was printed or not), we just need to mark the end of the group if ( keepTogetherSavePoint != null && i <= keepTogetherSavePoint.groupIndex ) { keepTogetherSavePoint = null; } } } if (savePoint != null) { savePoint.moveSavePointContent(); offsetY = columnFooterOffsetY; } } } /** * */ private SavePoint fillGroupFooter(JRFillGroup group, byte evaluation) throws JRException { SavePoint savePoint = null; JRFillSection groupFooterSection = (JRFillSection)group.getGroupFooterSection(); logger.debug("Fill " + fillerId + ": " + group.getName() + " footer at " + offsetY); JRFillBand[] groupFooterBands = groupFooterSection.getFillBands(); for(int i = 0; i < groupFooterBands.length; i++) { JRFillBand groupFooterBand = groupFooterBands[i]; groupFooterBand.evaluatePrintWhenExpression(evaluation); if (groupFooterBand.isToPrint()) { if ( groupFooterBand.getBreakHeight() > columnFooterOffsetY - offsetY ) { fillColumnBreak(evaluation, evaluation); } SavePoint newSavePoint = fillColumnBand(groupFooterBand, evaluation); newSavePoint.footerPosition = group.getFooterPositionValue(); savePoint = advanceSavePoint(savePoint, newSavePoint); isFirstPageBand = false; isFirstColumnBand = false; } } isNewPage = false; isNewColumn = false; group.setHeaderPrinted(false); group.setFooterPrinted(true); return savePoint; } /** * */ private void fillColumnFooter(byte evaluation) throws JRException { logger.debug("Fill " + fillerId + ": column footer at " + offsetY); setOffsetX(); /* if (!isSubreport) { offsetY = columnFooterOffsetY; } */ if (isSubreport() && !isSubreportRunToBottom() && columnIndex == 0) { columnFooterOffsetY = offsetY; } int oldOffsetY = offsetY; if (!isFloatColumnFooter && !fillContext.isIgnorePagination()) { offsetY = columnFooterOffsetY; } columnFooter.evaluatePrintWhenExpression(evaluation); if (columnFooter.isToPrint()) { fillFixedBand(columnFooter, evaluation); } if (isFloatColumnFooter && !fillContext.isIgnorePagination()) { offsetY += columnFooterOffsetY - oldOffsetY; } } /** * */ private void fillPageFooter(byte evaluation) throws JRException { JRFillBand crtPageFooter = getCurrentPageFooter(); logger.debug("Fill " + fillerId + ": " + (isLastPageFooter ? "last " : "") + "page footer at " + offsetY); offsetX = leftMargin; if ((!isSubreport() || isSubreportRunToBottom()) && !fillContext.isIgnorePagination()) { offsetY = pageHeight - crtPageFooter.getHeight() - bottomMargin; } crtPageFooter.evaluatePrintWhenExpression(evaluation); if (crtPageFooter.isToPrint()) { fillFixedBand(crtPageFooter, evaluation); } } /** * */ private void fillSummary() throws JRException { logger.debug("Fill " + fillerId + ": summary at " + offsetY); offsetX = leftMargin; if (lastPageFooter == missingFillBand) { if ( !isSummaryNewPage && columnIndex == 0 && summary.getBreakHeight() <= columnFooterOffsetY - offsetY ) { fillSummaryNoLastFooterSamePage(); } else { fillSummaryNoLastFooterNewPage(); } } else { if (isSummaryWithPageHeaderAndFooter) { fillSummaryWithLastFooterAndPageBands(); } else { fillSummaryWithLastFooterNoPageBands(); } } resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); resolveReportBoundElements(); } /** * */ private void fillSummaryNoLastFooterSamePage() throws JRException { summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY); if (summary.willOverflow() && summary.isSplitPrevented()) { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); if (isSummaryWithPageHeaderAndFooter) { fillPageHeader(JRExpression.EVALUATION_DEFAULT); } printBand = summary.refill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0)); fillBand(printBand); offsetY += printBand.getHeight(); } else { fillBand(printBand); offsetY += printBand.getHeight(); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); if (summary.willOverflow()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); if (isSummaryWithPageHeaderAndFooter) { fillPageHeader(JRExpression.EVALUATION_DEFAULT); } printBand = summary.fill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0)); fillBand(printBand); offsetY += printBand.getHeight(); } } /* */ fillSummaryOverflow(); //DONE } else { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); //DONE } } /** * */ private void fillSummaryNoLastFooterNewPage() throws JRException { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); if (isSummaryWithPageHeaderAndFooter) { fillPageHeader(JRExpression.EVALUATION_DEFAULT); } summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0)); if (summary.willOverflow() && summary.isSplitPrevented() && isSubreport()) { if (isSummaryWithPageHeaderAndFooter) { fillPageFooter(JRExpression.EVALUATION_DEFAULT); } resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); if (isSummaryWithPageHeaderAndFooter) { fillPageHeader(JRExpression.EVALUATION_DEFAULT); } printBand = summary.refill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0)); } fillBand(printBand); offsetY += printBand.getHeight(); /* */ fillSummaryOverflow(); } //DONE } /** * */ private void fillSummaryWithLastFooterAndPageBands() throws JRException { if ( !isSummaryNewPage && columnIndex == 0 && summary.getBreakHeight() <= columnFooterOffsetY - offsetY ) { summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY); if (summary.willOverflow() && summary.isSplitPrevented()) { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(JRExpression.EVALUATION_DEFAULT); printBand = summary.refill(pageHeight - bottomMargin - offsetY - pageFooter.getHeight()); fillBand(printBand); offsetY += printBand.getHeight(); } else { fillBand(printBand); offsetY += printBand.getHeight(); if (!summary.willOverflow()) { setLastPageFooter(true); } fillColumnFooter(JRExpression.EVALUATION_DEFAULT); } /* */ fillSummaryOverflow(); //DONE } else { setLastPageFooter(true); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); //DONE } } else if (columnIndex == 0 && offsetY <= lastPageColumnFooterOffsetY) { summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(JRExpression.EVALUATION_DEFAULT); summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - pageFooter.getHeight()); if (summary.willOverflow() && summary.isSplitPrevented() && isSubreport()) { fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(JRExpression.EVALUATION_DEFAULT); printBand = summary.refill(pageHeight - bottomMargin - offsetY - pageFooter.getHeight()); } fillBand(printBand); offsetY += printBand.getHeight(); /* */ fillSummaryOverflow(); //DONE } else { setLastPageFooter(true); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); //DONE } } else { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(JRExpression.EVALUATION_DEFAULT); summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - pageFooter.getHeight()); if (summary.willOverflow() && summary.isSplitPrevented() && isSubreport()) { fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(JRExpression.EVALUATION_DEFAULT); printBand = summary.refill(pageHeight - bottomMargin - offsetY - pageFooter.getHeight()); } fillBand(printBand); offsetY += printBand.getHeight(); /* */ fillSummaryOverflow(); //DONE } } /** * */ private void fillSummaryWithLastFooterNoPageBands() throws JRException { if ( !isSummaryNewPage && columnIndex == 0 && summary.getBreakHeight() <= lastPageColumnFooterOffsetY - offsetY ) { setLastPageFooter(true); summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY); if (summary.willOverflow() && summary.isSplitPrevented()) { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = summary.refill(pageHeight - bottomMargin - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } else { fillBand(printBand); offsetY += printBand.getHeight(); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); } /* */ fillSummaryOverflow(); //DONE } else { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); //DONE } } else if ( !isSummaryNewPage && columnIndex == 0 && summary.getBreakHeight() <= columnFooterOffsetY - offsetY ) { summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY); if (summary.willOverflow() && summary.isSplitPrevented()) { if (offsetY <= lastPageColumnFooterOffsetY) { setLastPageFooter(true); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = summary.refill(pageHeight - bottomMargin - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } else { fillPageBreak(false, JRExpression.EVALUATION_DEFAULT, JRExpression.EVALUATION_DEFAULT, false); setLastPageFooter(true); printBand = summary.refill(lastPageColumnFooterOffsetY - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); } } else { fillBand(printBand); offsetY += printBand.getHeight(); fillPageBreak(false, JRExpression.EVALUATION_DEFAULT, JRExpression.EVALUATION_DEFAULT, false); setLastPageFooter(true); if (summary.willOverflow()) { printBand = summary.fill(lastPageColumnFooterOffsetY - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); } /* */ fillSummaryOverflow(); //DONE } else { if(offsetY > lastPageColumnFooterOffsetY) { fillPageBreak(false, JRExpression.EVALUATION_DEFAULT, JRExpression.EVALUATION_DEFAULT, false); } setLastPageFooter(true); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); //DONE } } else if (columnIndex == 0 && offsetY <= lastPageColumnFooterOffsetY) { setLastPageFooter(true); fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY); if (summary.willOverflow() && summary.isSplitPrevented() && isSubreport()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = summary.refill(pageHeight - bottomMargin - offsetY); } fillBand(printBand); offsetY += printBand.getHeight(); /* */ fillSummaryOverflow(); } //DONE } else { fillColumnFooter(JRExpression.EVALUATION_DEFAULT); fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(JRExpression.EVALUATION_DEFAULT); //fillColumnHeader(JRExpression.EVALUATION_DEFAULT); setLastPageFooter(true); if (isSummaryNewPage) { fillPageFooter(JRExpression.EVALUATION_DEFAULT); summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY); if (summary.willOverflow() && summary.isSplitPrevented() && isSubreport()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = summary.refill(pageHeight - bottomMargin - offsetY); } fillBand(printBand); offsetY += printBand.getHeight(); /* */ fillSummaryOverflow(); } //DONE } else { summary.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (summary != missingFillBand && summary.isToPrint()) { summary.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = summary.fill(columnFooterOffsetY - offsetY); if (summary.willOverflow() && summary.isSplitPrevented())//FIXMENOW check subreport here? { fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = summary.refill(pageHeight - bottomMargin - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } else { fillBand(printBand); offsetY += printBand.getHeight(); fillPageFooter(JRExpression.EVALUATION_DEFAULT); } /* */ fillSummaryOverflow(); } else { fillPageFooter(JRExpression.EVALUATION_DEFAULT); } //DONE } } } /** * */ private void fillSummaryOverflow() throws JRException { while (summary.willOverflow()) { if (isSummaryWithPageHeaderAndFooter) { fillPageFooter(JRExpression.EVALUATION_DEFAULT); } resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); if (isSummaryWithPageHeaderAndFooter) { fillPageHeader(JRExpression.EVALUATION_DEFAULT); } JRPrintBand printBand = summary.fill(pageHeight - bottomMargin - offsetY - (isSummaryWithPageHeaderAndFooter?pageFooter.getHeight():0)); fillBand(printBand); offsetY += printBand.getHeight(); } resolveBandBoundElements(summary, JRExpression.EVALUATION_DEFAULT); if (isSummaryWithPageHeaderAndFooter) { if (offsetY > pageHeight - bottomMargin - lastPageFooter.getHeight()) { fillPageFooter(JRExpression.EVALUATION_DEFAULT); resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, true); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); fillPageHeader(JRExpression.EVALUATION_DEFAULT); } if (lastPageFooter != missingFillBand) { setLastPageFooter(true); } fillPageFooter(JRExpression.EVALUATION_DEFAULT); } } /** * */ private void fillBackground() throws JRException { logger.debug("Fill " + fillerId + ": background at " + offsetY); //offsetX = leftMargin; //if (!isSubreport) //{ // offsetY = pageHeight - pageFooter.getHeight() - bottomMargin; //} if (background.getHeight() <= pageHeight - bottomMargin - offsetY) { background.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (background.isToPrint()) { background.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = background.fill(pageHeight - bottomMargin - offsetY); fillBand(printBand); //offsetY += printBand.getHeight(); } } } /** * */ private void addPage(boolean isResetPageNumber) throws JRException { if (isSubreport()) { if (!parentFiller.isBandOverFlowAllowed()) { throw new JRRuntimeException("Subreport overflowed on a band that does not support overflow."); } //if ( // columnIndex == 0 || // (columnIndex > 0 && printPageStretchHeight < offsetY + bottomMargin) // ) //{ printPageStretchHeight = offsetY + bottomMargin; //} suspendSubreportRunner(); } printPage = newPage(); if (isResetPageNumber) { calculator.getPageNumber().setValue(Integer.valueOf(1)); } else { calculator.getPageNumber().setValue( Integer.valueOf(((Number)calculator.getPageNumber().getValue()).intValue() + 1) ); } calculator.getPageNumber().setOldValue( calculator.getPageNumber().getValue() ); addPage(printPage); setFirstColumn(); offsetY = topMargin; fillBackground(); } private void setFirstColumn() { columnIndex = 0; offsetX = leftMargin; setColumnNumberVar(); } private void setColumnNumberVar() { JRFillVariable columnNumber = calculator.getColumnNumber(); columnNumber.setValue(Integer.valueOf(columnIndex + 1)); columnNumber.setOldValue(columnNumber.getValue()); } /** * */ private void fillPageBreak( boolean isResetPageNumber, byte evalPrevPage, byte evalNextPage, boolean isReprintGroupHeaders ) throws JRException { if (isCreatingNewPage) { throw new JRException("Infinite loop creating new page."); } if (keepTogetherSavePoint != null) { keepTogetherSavePoint.saveEndOffsetY(offsetY); } isCreatingNewPage = true; fillColumnFooter(evalPrevPage); fillPageFooter(evalPrevPage); resolveGroupBoundElements(evalPrevPage, false); resolveColumnBoundElements(evalPrevPage); resolvePageBoundElements(evalPrevPage); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); if ( keepTogetherSavePoint != null && !keepTogetherSavePoint.isNewPage ) { keepTogetherSavePoint.removeContent(); } addPage(isResetPageNumber); fillPageHeader(evalNextPage); fillColumnHeader(evalNextPage); boolean savePointContentMoved = moveKeepTogetherSavePointContent(); if ( !savePointContentMoved && isReprintGroupHeaders ) { fillGroupHeadersReprint(evalNextPage); } isCreatingNewPage = false; } /** * */ private void fillColumnBreak( byte evalPrevPage, byte evalNextPage ) throws JRException { if (columnIndex == columnCount - 1) { fillPageBreak(false, evalPrevPage, evalNextPage, true); } else { if (keepTogetherSavePoint != null) { keepTogetherSavePoint.saveEndOffsetY(offsetY); } fillColumnFooter(evalPrevPage); resolveGroupBoundElements(evalPrevPage, false); resolveColumnBoundElements(evalPrevPage); scriptlet.callBeforeColumnInit(); calculator.initializeVariables(ResetTypeEnum.COLUMN, IncrementTypeEnum.COLUMN); scriptlet.callAfterColumnInit(); if ( keepTogetherSavePoint != null && !keepTogetherSavePoint.isNewColumn ) { keepTogetherSavePoint.removeContent(); } columnIndex += 1; setOffsetX(); offsetY = columnHeaderOffsetY; setColumnNumberVar(); fillColumnHeader(evalNextPage); moveKeepTogetherSavePointContent(); } } /** * */ protected void fillPageBand(JRFillBand band, byte evaluation) throws JRException { band.evaluate(evaluation); JRPrintBand printBand = band.fill(columnFooterOffsetY - offsetY); if (band.willOverflow() && band.isSplitPrevented()) { fillPageBreak(false, evaluation, evaluation, true); printBand = band.refill(columnFooterOffsetY - offsetY); } fillBand(printBand); offsetY += printBand.getHeight(); while (band.willOverflow()) { fillPageBreak(false, evaluation, evaluation, true); printBand = band.fill(columnFooterOffsetY - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } resolveBandBoundElements(band, evaluation); } /** * */ protected SavePoint fillColumnBand(JRFillBand band, byte evaluation) throws JRException { band.evaluate(evaluation); JRPrintBand printBand = band.fill(columnFooterOffsetY - offsetY); if ( band.willOverflow() && (band.isSplitPrevented() || keepTogetherSavePoint != null) ) { fillColumnBreak(evaluation, evaluation); printBand = band.refill(columnFooterOffsetY - offsetY); } SavePoint savePoint = new SavePoint( getCurrentPage(), columnIndex, isNewPage, isNewColumn, offsetY ); fillBand(printBand); offsetY += printBand.getHeight(); savePoint.saveHeightOffset(columnFooterOffsetY - offsetY); // we mark the save point here, because overflow content beyond this point // should be rendered normally, not moved in any way while (band.willOverflow()) { fillColumnBreak(evaluation, evaluation); printBand = band.fill(columnFooterOffsetY - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } resolveBandBoundElements(band, evaluation); return savePoint; } /** * */ protected void fillFixedBand(JRFillBand band, byte evaluation) throws JRException { band.evaluate(evaluation); JRPrintBand printBand = band.fill(); fillBand(printBand); offsetY += printBand.getHeight(); resolveBandBoundElements(band, evaluation); } /** * */ protected void fillBand(JRPrintBand band) { for(Iterator<JRPrintElement> it = band.iterateElements(); it.hasNext();) { JRPrintElement element = it.next(); element.setX(element.getX() + offsetX); element.setY(element.getY() + offsetY); printPage.addElement(element); } } /** * */ private void setNewPageColumnInBands() { title.setNewPageColumn(true); pageHeader.setNewPageColumn(true); columnHeader.setNewPageColumn(true); detailSection.setNewPageColumn(true); columnFooter.setNewPageColumn(true); pageFooter.setNewPageColumn(true); lastPageFooter.setNewPageColumn(true); summary.setNewPageColumn(true); noData.setNewPageColumn(true); if (groups != null && groups.length > 0) { for(int i = 0; i < groups.length; i++) { ((JRFillSection)groups[i].getGroupHeaderSection()).setNewPageColumn(true); ((JRFillSection)groups[i].getGroupFooterSection()).setNewPageColumn(true); } } } /** * */ private void setNewGroupInBands(JRGroup group) { title.setNewGroup(group, true); pageHeader.setNewGroup(group, true); columnHeader.setNewGroup(group, true); detailSection.setNewGroup(group, true); columnFooter.setNewGroup(group, true); pageFooter.setNewGroup(group, true); lastPageFooter.setNewGroup(group, true); summary.setNewGroup(group, true); noData.setNewGroup(group, true); if (groups != null && groups.length > 0) { for(int i = 0; i < groups.length; i++) { ((JRFillSection)groups[i].getGroupHeaderSection()).setNewGroup(group, true); ((JRFillSection)groups[i].getGroupFooterSection()).setNewGroup(group, true); } } } /** * */ private JRFillBand getCurrentPageFooter() { return isLastPageFooter ? lastPageFooter : pageFooter; } /** * */ private void setLastPageFooter(boolean isLastPageFooter) { this.isLastPageFooter = isLastPageFooter; if (isLastPageFooter) { columnFooterOffsetY = lastPageColumnFooterOffsetY; } } /** * */ private void fillNoData() throws JRException { logger.debug("Fill " + fillerId + ": noData at " + offsetY); noData.evaluatePrintWhenExpression(JRExpression.EVALUATION_DEFAULT); if (noData.isToPrint()) { while (noData.getBreakHeight() > pageHeight - bottomMargin - offsetY) { addPage(false); } noData.evaluate(JRExpression.EVALUATION_DEFAULT); JRPrintBand printBand = noData.fill(pageHeight - bottomMargin - offsetY); if (noData.willOverflow() && noData.isSplitPrevented() && isSubreport()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = noData.refill(pageHeight - bottomMargin - offsetY); } fillBand(printBand); offsetY += printBand.getHeight(); while (noData.willOverflow()) { resolveGroupBoundElements(JRExpression.EVALUATION_DEFAULT, false); resolveColumnBoundElements(JRExpression.EVALUATION_DEFAULT); resolvePageBoundElements(JRExpression.EVALUATION_DEFAULT); scriptlet.callBeforePageInit(); calculator.initializeVariables(ResetTypeEnum.PAGE, IncrementTypeEnum.PAGE); scriptlet.callAfterPageInit(); addPage(false); printBand = noData.fill(pageHeight - bottomMargin - offsetY); fillBand(printBand); offsetY += printBand.getHeight(); } resolveBandBoundElements(noData, JRExpression.EVALUATION_DEFAULT); } } /** * */ private void setOffsetX() { if (columnDirection == RunDirectionEnum.RTL) { offsetX = pageWidth - rightMargin - columnWidth - columnIndex * (columnSpacing + columnWidth); } else { offsetX = leftMargin + columnIndex * (columnSpacing + columnWidth); } } //Methods that are out of scope (visibility) /** * */ private void baseInit() { JasperReportsContext localContext = LocalJasperReportsContext.getLocalContext(getJasperReportsContext(), parameterValues); if (localContext != getJasperReportsContext()) { setJasperReportsContext(localContext); } // fillingThread = Thread.currentThread(); try { boundElements = new HashMap<JREvaluationTime, LinkedHashMap<PageKey, LinkedMap<Object, EvaluationBoundAction>>>(); createBoundElementMaps(JREvaluationTime.EVALUATION_TIME_REPORT); createBoundElementMaps(JREvaluationTime.EVALUATION_TIME_PAGE); createBoundElementMaps(JREvaluationTime.EVALUATION_TIME_COLUMN); if (groups != null) { for (int i = 0; i < groups.length; i++) { createBoundElementMaps(JREvaluationTime.getGroupEvaluationTime(groups[i].getName())); } } for (Iterator<JRBand> i = bands.iterator(); i.hasNext();) { JRFillBand band = (JRFillBand) i.next(); createBoundElementMaps(JREvaluationTime.getBandEvaluationTime(band)); } if (parentFiller != null) { parentFiller.registerSubfiller(this); } setParameters(parameterValues); loadStyles(); jasperPrint.setName(name); jasperPrint.setPageWidth(pageWidth); jasperPrint.setPageHeight(pageHeight); jasperPrint.setTopMargin(topMargin); jasperPrint.setLeftMargin(leftMargin); jasperPrint.setBottomMargin(bottomMargin); jasperPrint.setRightMargin(rightMargin); jasperPrint.setOrientation(orientation); jasperPrint.setFormatFactoryClass(jasperReport.getFormatFactoryClass()); jasperPrint.setLocaleCode(JRDataUtils.getLocaleCode(getLocale())); jasperPrint.setTimeZoneId(JRDataUtils.getTimeZoneId(getTimeZone())); jasperPrint.setDefaultStyle(defaultStyle); /* */ if (styles != null && styles.length > 0) { for (int i = 0; i < styles.length; i++) { addPrintStyle(styles[i]); } } /* */ //Done in write(List<T>) mainDataset.start(); } catch (Exception e) { logger.error("Unable to initialise report", e); } } /** * @param evaluationTime */ private void createBoundElementMaps(JREvaluationTime evaluationTime) { LinkedHashMap<PageKey, LinkedMap<Object, EvaluationBoundAction>> boundElementsMap = new LinkedHashMap<PageKey, LinkedMap<Object, EvaluationBoundAction>>(); boundElements.put(evaluationTime, boundElementsMap); } /** * */ private void baseClose() { getMainDataset().closeDatasource(); getMainDataset().disposeParameterContributors(); if (parentFiller == null) { // commit the cached data fillContext.cacheDone(); } if (parentFiller != null) { parentFiller.unregisterSubfiller(this); } if (fillContext.isUsingVirtualizer()) { // removing the listener virtualizationContext.removeListener(virtualizationListener); } if (parentFiller == null) { fillContext.dispose(); } } }