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: * PrintReportProcessor.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.modules.output.pageable.graphics;
030:
031: import java.awt.print.PageFormat;
032: import java.awt.print.Pageable;
033: import java.awt.print.Printable;
034:
035: import org.jfree.report.EmptyReportException;
036: import org.jfree.report.JFreeReport;
037: import org.jfree.report.ReportInterruptedException;
038: import org.jfree.report.ReportProcessingException;
039: import org.jfree.report.layout.output.PageState;
040: import org.jfree.report.modules.output.pageable.base.PageableReportProcessor;
041: import org.jfree.report.modules.output.pageable.graphics.internal.DrawablePrintable;
042: import org.jfree.report.modules.output.pageable.graphics.internal.GraphicsOutputProcessor;
043: import org.jfree.report.modules.output.pageable.graphics.internal.QueryPhysicalPageInterceptor;
044: import org.jfree.util.Log;
045:
046: /**
047: * Creation-Date: 09.04.2007, 13:28:33
048: *
049: * @author Thomas Morgner
050: */
051: public class PrintReportProcessor extends PageableReportProcessor
052: implements Pageable {
053: private Throwable error;
054:
055: public PrintReportProcessor(final JFreeReport report)
056: throws ReportProcessingException {
057: super (report, new GraphicsOutputProcessor(report
058: .getConfiguration()));
059:
060: }
061:
062: protected GraphicsOutputProcessor getGraphicsProcessor() {
063: return (GraphicsOutputProcessor) getOutputProcessor();
064: }
065:
066: /**
067: * Returns the number of pages in the set. To enable advanced printing
068: * features, it is recommended that <code>Pageable</code> implementations
069: * return the true number of pages rather than the UNKNOWN_NUMBER_OF_PAGES
070: * constant.
071: *
072: * @return the number of pages in this <code>Pageable</code>.
073: */
074: public synchronized int getNumberOfPages() {
075: if (isError()) {
076: return 0;
077: }
078:
079: if (isPaginated() == false) {
080: try {
081: prepareReportProcessing();
082: Log.debug("After pagination, we have "
083: + getGraphicsProcessor().getPhysicalPageCount()
084: + " physical pages.");
085: } catch (ReportInterruptedException e) {
086: error = e;
087: return 0;
088: } catch (Exception e) {
089: Log.debug("PrintReportProcessor: ", e);
090: error = e;
091: return 0;
092: }
093: }
094: return getGraphicsProcessor().getPhysicalPageCount();
095: }
096:
097: /**
098: * Manually triggers the pagination. This method will block until the pagination is finished and will do nothing
099: * if an error occured.
100: *
101: * @return true, if the pagination was successfull, false otherwise.
102: */
103: public boolean paginate() {
104: if (isError()) {
105: return false;
106: }
107:
108: if (isPaginated() == false) {
109: try {
110: prepareReportProcessing();
111: return true;
112: } catch (ReportInterruptedException e) {
113: error = e;
114: return false;
115: } catch (Exception e) {
116: error = e;
117: return false;
118: }
119: }
120: return true;
121: }
122:
123: /**
124: * Returns the <code>PageFormat</code> of the page specified by
125: * <code>pageIndex</code>.
126: *
127: * @param pageIndex the zero based index of the page whose <code>PageFormat</code>
128: * is being requested
129: * @return the <code>PageFormat</code> describing the size and orientation.
130: * @throws IndexOutOfBoundsException if the <code>Pageable</code> does not
131: * contain the requested page.
132: */
133: public synchronized PageFormat getPageFormat(final int pageIndex)
134: throws IndexOutOfBoundsException {
135: if (isError()) {
136: return null;
137: }
138:
139: if (isPaginated() == false) {
140: try {
141: prepareReportProcessing();
142: } catch (ReportInterruptedException e) {
143: error = e;
144: return null;
145: } catch (Exception e) {
146: error = e;
147: return null;
148: }
149: }
150:
151: try {
152: final PageDrawable pageDrawable = processPage(pageIndex);
153: return pageDrawable.getPageFormat();
154: } catch (Exception e) {
155: throw new IllegalStateException(
156: "Unable to return a valid pageformat.");
157: }
158: }
159:
160: /**
161: * Returns the <code>Printable</code> instance responsible for rendering the
162: * page specified by <code>pageIndex</code>.
163: *
164: * @param pageIndex the zero based index of the page whose <code>Printable</code>
165: * is being requested
166: * @return the <code>Printable</code> that renders the page.
167: * @throws IndexOutOfBoundsException if the <code>Pageable</code> does not
168: * contain the requested page.
169: */
170: public synchronized Printable getPrintable(final int pageIndex)
171: throws IndexOutOfBoundsException {
172: if (isError()) {
173: return null;
174: }
175:
176: if (isPaginated() == false) {
177: try {
178: prepareReportProcessing();
179: } catch (ReportInterruptedException e) {
180: error = e;
181: return null;
182: } catch (Exception e) {
183: error = e;
184: return null;
185: }
186: }
187:
188: try {
189: final PageDrawable pageDrawable = processPage(pageIndex);
190: return new DrawablePrintable(pageDrawable);
191: } catch (Exception e) {
192: Log.error("Failed to return a valid pageable object: ", e);
193: throw new IllegalStateException(
194: "Unable to return a valid pageformat.");
195: }
196: }
197:
198: /**
199: * Returns the <code>PageDrawable</code> instance responsible for rendering the
200: * page specified by <code>pageIndex</code>.
201: *
202: * @param pageIndex the zero based index of the page whose <code>Printable</code>
203: * is being requested
204: * @return the <code>PageDrawable</code> that renders the page.
205: * @throws IndexOutOfBoundsException if the <code>Pageable</code> does not
206: * contain the requested page.
207: */
208: public PageDrawable getPageDrawable(final int pageIndex) {
209: if (isError()) {
210: return null;
211: }
212:
213: if (isPaginated() == false) {
214: try {
215: prepareReportProcessing();
216: } catch (ReportInterruptedException e) {
217: error = e;
218: return null;
219: } catch (Exception e) {
220: error = e;
221: return null;
222: }
223: }
224:
225: try {
226: return processPage(pageIndex);
227: } catch (Exception e) {
228: error = e;
229: Log.debug("Failed to process the page", e);
230: throw new IllegalStateException(
231: "Unable to return a valid pageformat.");
232: }
233: }
234:
235: /**
236: * An internal method that returns the page-drawable for the given page.
237: *
238: * @param page the page number.
239: * @return the pagedrawable for the given page.
240: * @throws ReportProcessingException if an error occured while processing the report.
241: */
242: protected PageDrawable processPage(final int page)
243: throws ReportProcessingException {
244: final GraphicsOutputProcessor outputProcessor = getGraphicsProcessor();
245: try {
246: // set up the scene. We can assume that the report has been paginated by now ..
247: final PageState state = getPhysicalPageState(page);
248: final QueryPhysicalPageInterceptor interceptor = new QueryPhysicalPageInterceptor(
249: outputProcessor.getPhysicalPage(page));
250: outputProcessor.setInterceptor(interceptor);
251: processPage(state, true);
252: return interceptor.getDrawable();
253: } finally {
254: outputProcessor.setInterceptor(null);
255: }
256: }
257:
258: /**
259: * Checks, whether an error occured. The Exception itself can be queried using 'getErrorReason()'.
260: *
261: * @return true, if an error occured, false otherwise.
262: */
263: public boolean isError() {
264: return error != null;
265: }
266:
267: /**
268: * This method throws an UnsupportedOperationException as printing is a passive process and cannot be started
269: * here. To print the whole report, use this Pageable implementation and pass it to one of the JDKs printing
270: * sub-systems.
271: *
272: * @throws ReportProcessingException
273: * @throws EmptyReportException
274: */
275: public void processReport() throws ReportProcessingException {
276: throw new UnsupportedOperationException(
277: "Printing is a passive process.");
278: }
279:
280: /**
281: * Returns the last exception that has been caught.
282: *
283: * @return the error reason.
284: */
285: public Throwable getErrorReason() {
286: return error;
287: }
288: }
|