Source for org.jfree.report.modules.gui.swing.printing.PrintReportProcessor

   1: /**
   2:  * ========================================
   3:  * JFreeReport : a free Java report library
   4:  * ========================================
   5:  *
   6:  * Project Info:  http://reporting.pentaho.org/
   7:  *
   8:  * (C) Copyright 2000-2007, by Object Refinery Limited, Pentaho Corporation and Contributors.
   9:  *
  10:  * This library is free software; you can redistribute it and/or modify it under the terms
  11:  * of the GNU Lesser General Public License as published by the Free Software Foundation;
  12:  * either version 2.1 of the License, or (at your option) any later version.
  13:  *
  14:  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
  15:  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16:  * See the GNU Lesser General Public License for more details.
  17:  *
  18:  * You should have received a copy of the GNU Lesser General Public License along with this
  19:  * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  20:  * Boston, MA 02111-1307, USA.
  21:  *
  22:  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
  23:  * in the United States and other countries.]
  24:  *
  25:  * ------------
  26:  * $Id: PrintReportProcessor.java 3525 2007-10-16 11:43:48Z tmorgner $
  27:  * ------------
  28:  * (C) Copyright 2000-2005, by Object Refinery Limited.
  29:  * (C) Copyright 2005-2007, by Pentaho Corporation.
  30:  */
  31: 
  32: package org.jfree.report.modules.gui.swing.printing;
  33: 
  34: import java.awt.print.PageFormat;
  35: import java.awt.print.Pageable;
  36: import java.awt.print.Printable;
  37: 
  38: import org.jfree.layouting.StateException;
  39: import org.jfree.layouting.modules.output.graphics.GraphicsOutputProcessor;
  40: import org.jfree.layouting.modules.output.graphics.PageDrawable;
  41: import org.jfree.layouting.modules.output.graphics.QueryPhysicalPageInterceptor;
  42: import org.jfree.report.DataSourceException;
  43: import org.jfree.report.ReportDataFactory;
  44: import org.jfree.report.ReportDataFactoryException;
  45: import org.jfree.report.ReportProcessingException;
  46: import org.jfree.report.flow.LibLayoutReportTarget;
  47: import org.jfree.report.flow.ReportJob;
  48: import org.jfree.report.flow.ReportTargetState;
  49: import org.jfree.report.flow.layoutprocessor.LayoutController;
  50: import org.jfree.report.flow.paginating.PageState;
  51: import org.jfree.report.flow.paginating.PaginatingReportProcessor;
  52: import org.jfree.util.Log;
  53: 
  54: /**
  55:  * A paginating report processor that outputs to Pageables.
  56:  *
  57:  * @author Thomas Morgner
  58:  */
  59: public class PrintReportProcessor extends PaginatingReportProcessor
  60:     implements Pageable
  61: {
  62:   private ReportJob job;
  63:   private Throwable error;
  64: 
  65:   public PrintReportProcessor(final ReportJob job)
  66:   {
  67:     super(new GraphicsOutputProcessor(job.getConfiguration()));
  68:     this.job = job;
  69: 
  70:     synchronized(job)
  71:     {
  72:       final ReportDataFactory dataFactory = job.getDataFactory();
  73:       if (dataFactory != null)
  74:       {
  75:         dataFactory.open();
  76:       }
  77:     }
  78:   }
  79: 
  80:   protected GraphicsOutputProcessor getGraphicsProcessor()
  81:   {
  82:     return (GraphicsOutputProcessor) getOutputProcessor();
  83:   }
  84: 
  85:   public boolean isError()
  86:   {
  87:     return error != null;
  88:   }
  89: 
  90:   protected ReportJob getJob()
  91:   {
  92:     return job;
  93:   }
  94: 
  95:   public void close()
  96:   {
  97:     getJob().close();
  98:   }
  99: 
 100:   protected PageDrawable processPage(final int page)
 101:       throws ReportDataFactoryException,
 102:       DataSourceException, ReportProcessingException, StateException
 103:   {
 104:     final ReportJob job = getJob();
 105:     synchronized (job)
 106:     {
 107:       // set up the scene
 108:       final PageState state = getPhysicalPageState(page);
 109: 
 110:       final ReportTargetState targetState = state.getTargetState();
 111:       final GraphicsOutputProcessor outputProcessor = getGraphicsProcessor();
 112:       outputProcessor.setPageCursor(state.getPageCursor());
 113:       final QueryPhysicalPageInterceptor interceptor =
 114:           new QueryPhysicalPageInterceptor(outputProcessor.getPhysicalPage(page));
 115:       outputProcessor.setInterceptor(interceptor);
 116: 
 117:       final LibLayoutReportTarget target =
 118:           (LibLayoutReportTarget) targetState.restore(outputProcessor);
 119: 
 120:       LayoutController position = state.getLayoutController();
 121: 
 122:       // we have the data and we have our position inside the report.
 123:       // lets generate something ...
 124:       while (position.isAdvanceable())
 125:       {
 126:         position = position.advance(target);
 127:         target.commit();
 128: 
 129:         while (position.isAdvanceable() == false &&
 130:                position.getParent() != null)
 131:         {
 132:           final LayoutController parent = position.getParent();
 133:           position = parent.join(position.getFlowController());
 134:         }
 135: 
 136:         if (interceptor.isMoreContentNeeded() == false)
 137:         {
 138:           outputProcessor.setInterceptor(null);
 139:           return interceptor.getDrawable();
 140:         }
 141: 
 142:       }
 143: 
 144:       outputProcessor.setInterceptor(null);
 145:       return interceptor.getDrawable();
 146:     }
 147:   }
 148: 
 149:   /**
 150:    * Returns the number of pages in the set. To enable advanced printing
 151:    * features, it is recommended that <code>Pageable</code> implementations
 152:    * return the true number of pages rather than the UNKNOWN_NUMBER_OF_PAGES
 153:    * constant.
 154:    *
 155:    * @return the number of pages in this <code>Pageable</code>.
 156:    */
 157:   public synchronized int getNumberOfPages()
 158:   {
 159:     if (isError())
 160:     {
 161:       return 0;
 162:     }
 163: 
 164:     if (isPaginated() == false)
 165:     {
 166:       try
 167:       {
 168:         prepareReportProcessing(getJob());
 169:       }
 170:       catch (Exception e)
 171:       {
 172:         Log.debug("PrintReportProcessor: ", e);
 173:         error = e;
 174:         return 0;
 175:       }
 176:     }
 177:     Log.debug ("After pagination, we have " +
 178:         getGraphicsProcessor().getPhysicalPageCount() + " physical pages.");
 179:     return getGraphicsProcessor().getPhysicalPageCount();
 180:   }
 181: 
 182:   public boolean paginate()
 183:   {
 184:     if (isError())
 185:     {
 186:       return false;
 187:     }
 188: 
 189:     if (isPaginated() == false)
 190:     {
 191:       try
 192:       {
 193:         prepareReportProcessing(getJob());
 194:         return true;
 195:       }
 196:       catch (Exception e)
 197:       {
 198:         error = e;
 199:         return false;
 200:       }
 201:     }
 202:     return true;
 203:   }
 204: 
 205:   /**
 206:    * Returns the <code>PageFormat</code> of the page specified by
 207:    * <code>pageIndex</code>.
 208:    *
 209:    * @param pageIndex the zero based index of the page whose <code>PageFormat</code>
 210:    *                  is being requested
 211:    * @return the <code>PageFormat</code> describing the size and orientation.
 212:    * @throws IndexOutOfBoundsException if the <code>Pageable</code> does not
 213:    *                                   contain the requested page.
 214:    */
 215:   public synchronized PageFormat getPageFormat(final int pageIndex)
 216:       throws IndexOutOfBoundsException
 217:   {
 218:     if (isError())
 219:     {
 220:       return null;
 221:     }
 222: 
 223:     if (isPaginated() == false)
 224:     {
 225:       try
 226:       {
 227:         prepareReportProcessing(getJob());
 228:       }
 229:       catch (Exception e)
 230:       {
 231:         error = e;
 232:         return null;
 233:       }
 234:     }
 235: 
 236:     try
 237:     {
 238:       final PageDrawable pageDrawable = processPage(pageIndex);
 239:       return pageDrawable.getPageFormat();
 240:     }
 241:     catch (Exception e)
 242:     {
 243:       throw new IllegalStateException("Unable to return a valid pageformat.");
 244:     }
 245:   }
 246: 
 247:   /**
 248:    * Returns the <code>Printable</code> instance responsible for rendering the
 249:    * page specified by <code>pageIndex</code>.
 250:    *
 251:    * @param pageIndex the zero based index of the page whose <code>Printable</code>
 252:    *                  is being requested
 253:    * @return the <code>Printable</code> that renders the page.
 254:    * @throws IndexOutOfBoundsException if the <code>Pageable</code> does not
 255:    *                                   contain the requested page.
 256:    */
 257:   public synchronized Printable getPrintable(final int pageIndex)
 258:       throws IndexOutOfBoundsException
 259:   {
 260:     if (isError())
 261:     {
 262:       return null;
 263:     }
 264: 
 265:     if (isPaginated() == false)
 266:     {
 267:       try
 268:       {
 269:         prepareReportProcessing(getJob());
 270:       }
 271:       catch (Exception e)
 272:       {
 273:         error = e;
 274:         return null;
 275:       }
 276:     }
 277: 
 278:     try
 279:     {
 280:       final PageDrawable pageDrawable = processPage(pageIndex);
 281:       return new DrawablePrintable(pageDrawable);
 282:     }
 283:     catch (Exception e)
 284:     {
 285:       throw new IllegalStateException("Unable to return a valid pageformat.");
 286:     }
 287:   }
 288: 
 289:   public PageDrawable getPageDrawable(final int pageIndex)
 290:   {
 291:     if (isError())
 292:     {
 293:       return null;
 294:     }
 295: 
 296:     if (isPaginated() == false)
 297:     {
 298:       try
 299:       {
 300:         prepareReportProcessing(getJob());
 301:       }
 302:       catch (Exception e)
 303:       {
 304:         error = e;
 305:         return null;
 306:       }
 307:     }
 308: 
 309:     try
 310:     {
 311:       return processPage(pageIndex);
 312:     }
 313:     catch (Exception e)
 314:     {
 315:       error = e;
 316:       Log.debug("Failed to process the page", e);
 317:       throw new IllegalStateException("Unable to return a valid pageformat.");
 318:     }
 319:   }
 320: 
 321:   /**
 322:    * Throws an unsupported operation exception. Printing is controlled by a
 323:    * framework which calls this pageable class for each page. Therefore,
 324:    * printing has to be invoked from outside.
 325:    *
 326:    * @param job
 327:    * @throws UnsupportedOperationException
 328:    */
 329:   public final void processReport(final ReportJob job)
 330:   {
 331:     throw new UnsupportedOperationException("Printing is a passive process.");
 332:   }
 333: }