001: /**
002: * ===========================================
003: * JFreeReport : a free Java reporting library
004: * ===========================================
005: *
006: * Project Info: http://reporting.pentaho.org/
007: *
008: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009: *
010: * This library is free software; you can redistribute it and/or modify it under the terms
011: * of the GNU Lesser General Public License as published by the Free Software Foundation;
012: * either version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015: * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016: * See the GNU Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public License along with this
019: * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: *
022: * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023: * in the United States and other countries.]
024: *
025: * ------------
026: * PageableRenderer.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.modules.output.pageable.base;
030:
031: import org.jfree.report.PageDefinition;
032: import org.jfree.report.layout.AbstractRenderer;
033: import org.jfree.report.layout.FileModelPrinter;
034: import org.jfree.report.layout.ModelPrinter;
035: import org.jfree.report.layout.model.LogicalPageBox;
036: import org.jfree.report.layout.output.ContentProcessingException;
037: import org.jfree.report.layout.output.LayoutPagebreakHandler;
038: import org.jfree.report.layout.output.OutputProcessor;
039: import org.jfree.report.layout.process.ApplyPageShiftValuesStep;
040: import org.jfree.report.layout.process.CleanPaginatedBoxesStep;
041: import org.jfree.report.layout.process.FillPhysicalPagesStep;
042: import org.jfree.report.layout.process.PaginationResult;
043: import org.jfree.report.layout.process.PaginationStep;
044: import org.jfree.report.util.InstanceID;
045: import org.jfree.util.Log;
046:
047: /**
048: * Creation-Date: 08.04.2007, 15:08:48
049: *
050: * @author Thomas Morgner
051: */
052: public class PageableRenderer extends AbstractRenderer {
053: private PaginationStep paginationStep;
054: private FillPhysicalPagesStep fillPhysicalPagesStep;
055: private CleanPaginatedBoxesStep cleanPaginatedBoxesStep;
056: private ApplyPageShiftValuesStep applyPageShiftValuesStep;
057: private int pageCount;
058: private long lastPageAge;
059: private boolean pageStartPending;
060:
061: public PageableRenderer(final OutputProcessor outputProcessor) {
062: super (outputProcessor);
063: this .paginationStep = new PaginationStep();
064: this .fillPhysicalPagesStep = new FillPhysicalPagesStep();
065: this .cleanPaginatedBoxesStep = new CleanPaginatedBoxesStep();
066: this .applyPageShiftValuesStep = new ApplyPageShiftValuesStep();
067: this .lastPageAge = System.currentTimeMillis();
068: }
069:
070: public void startReport(final PageDefinition pageDefinition) {
071: final long prePageAge = System.currentTimeMillis();
072: Log.debug("Time to pagination " + (prePageAge - lastPageAge));
073: this .lastPageAge = prePageAge;
074:
075: super .startReport(pageDefinition);
076: pageCount = 0;
077: }
078:
079: // protected void debugPrint(final LogicalPageBox pageBox)
080: // {
081: // Log.debug("**** Start Printing Page: " + pageCount);
082: // ModelPrinter.print(pageBox);
083: // Log.debug("**** Done Printing Page: " + pageCount);
084: // }
085:
086: protected boolean isPageFinished() {
087: final LogicalPageBox pageBox = getPageBox();
088: // final long sizeBeforePagination = pageBox.getHeight();
089: // final LogicalPageBox clone = (LogicalPageBox) pageBox.derive(true);
090: final PaginationResult pageBreak = paginationStep
091: .performPagebreak(pageBox);
092: if (pageBreak.isOverflow() || pageBox.isOpen() == false) {
093: setLastStateKey(pageBreak.getLastVisibleState());
094: return true;
095: }
096: return false;
097: }
098:
099: protected boolean performPagination(
100: final LayoutPagebreakHandler layoutPagebreakHandler,
101: final boolean performOutput)
102: throws ContentProcessingException {
103: // next: perform pagination.
104: final LogicalPageBox pageBox = getPageBox();
105:
106: // final long sizeBeforePagination = pageBox.getHeight();
107: // final LogicalPageBox clone = (LogicalPageBox) pageBox.derive(true);
108: final PaginationResult pageBreak = paginationStep
109: .performPagebreak(pageBox);
110: if (pageBreak.isOverflow() || pageBox.isOpen() == false) {
111: // final long sizeAfterPagination = pageBox.getHeight();
112: setLastStateKey(pageBreak.getLastVisibleState());
113: setPagebreaks(getPagebreaks() + 1);
114: pageBox.setAllVerticalBreaks(pageBreak.getAllBreaks());
115:
116: pageCount += 1;
117: debugPrint(pageBox);
118:
119: // A new page has been started. Recover the page-grid, then restart
120: // everything from scratch. (We have to recompute, as the pages may
121: // be different now, due to changed margins or page definitions)
122: final OutputProcessor outputProcessor = getOutputProcessor();
123: final long nextOffset = pageBreak.getLastPosition();
124: final long pageOffset = pageBox.getPageOffset();
125:
126: if (performOutput) {
127: if (outputProcessor.isNeedAlignedPage()) {
128: final LogicalPageBox box = fillPhysicalPagesStep
129: .compute(pageBox, pageOffset, nextOffset);
130: outputProcessor.processContent(box);
131: // ModelPrinter.print(box);
132: // Log.debug("Processing contents for Page " + pageCount + " Page-Offset: " + pageOffset + " -> " + nextOffset);
133: } else {
134: // Log.debug("Processing fast contents for Page " + pageCount + " Page-Offset: " + pageOffset + " -> " + nextOffset);
135: outputProcessor.processContent(pageBox);
136: }
137: } else {
138: // todo: When recomputing the contents, we have to update the page cursor or the whole
139: // excercise is next to useless ..
140: // Log.debug("Recomputing contents for Page " + pageCount + " Page-Offset: " + pageOffset + " -> " + nextOffset);
141: outputProcessor.processRecomputedContent(pageBox);
142: }
143:
144: // Now fire the pagebreak. This goes through all layers and informs all
145: // components, that a pagebreak has been encountered and possibly a
146: // new page has been set. It does not save the state or perform other
147: // expensive operations. However, it updates the 'isPagebreakEncountered'
148: // flag, which will be active until the input-feed received a new event.
149: final long currentPageAge = System.currentTimeMillis();
150: // Log.debug ("PageTime " + (currentPageAge - lastPageAge));
151: lastPageAge = currentPageAge;
152:
153: final boolean repeat = pageBox.isOpen()
154: || (pageBox.getHeight() > nextOffset);
155: if (repeat) {
156: // Log.debug(new MemoryUsageMessage("PAGEBREAK ENCOUNTERED"));
157: //Log.debug("Page-Offset: " + pageOffset + " -> " + nextOffset);
158:
159: pageBox.setPageOffset(nextOffset);
160:
161: final long l = cleanPaginatedBoxesStep.compute(pageBox);
162: if (l > 0) {
163: final InstanceID shiftNode = cleanPaginatedBoxesStep
164: .getShiftNode();
165: applyPageShiftValuesStep.compute(pageBox, l,
166: shiftNode);
167: debugPrint(pageBox);
168: }
169: if (pageBreak.isNextPageContainsContent()) {
170: if (layoutPagebreakHandler != null) {
171: layoutPagebreakHandler.pageStarted();
172: }
173: return true;
174: }
175: // No need to try again, we know that the result will not change, as the next page is
176: // empty. (We already tested it.)
177: pageStartPending = true;
178: return false;
179: } else {
180: pageBox.setPageOffset(nextOffset);
181: outputProcessor.processingFinished();
182: return false;
183: }
184: }
185: return false;
186: }
187:
188: public boolean clearPendingPageStart(
189: final LayoutPagebreakHandler layoutPagebreakHandler) {
190: if (pageStartPending == false) {
191: return false;
192: }
193:
194: if (layoutPagebreakHandler != null) {
195: layoutPagebreakHandler.pageStarted();
196: }
197: pageStartPending = false;
198: return true;
199: }
200:
201: public int getPageCount() {
202: return pageCount;
203: }
204:
205: public boolean isPageStartPending() {
206: return pageStartPending;
207: }
208: }
|