Source for org.jfree.report.flow.layoutprocessor.BufferingLayoutController

   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: BufferingLayoutController.java 2725 2007-04-01 18:49:29Z taqua $
  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.flow.layoutprocessor;
  33: 
  34: import org.jfree.report.DataSourceException;
  35: import org.jfree.report.ReportDataFactoryException;
  36: import org.jfree.report.ReportProcessingException;
  37: import org.jfree.report.flow.FlowController;
  38: import org.jfree.report.flow.ReportTarget;
  39: 
  40: /**
  41:  * Todo: Document me!
  42:  *
  43:  * @author Thomas Morgner
  44:  * @since 05.03.2007
  45:  */
  46: public abstract class BufferingLayoutController
  47:     extends AbstractLayoutController
  48: {
  49:   private BufferedReportTarget reportTarget;
  50:   private LayoutController delegate;
  51:   private boolean finished;
  52: 
  53:   protected BufferingLayoutController()
  54:   {
  55:     reportTarget = new BufferedReportTarget();
  56:   }
  57: 
  58:   /**
  59:    * Advances the processing position.
  60:    *
  61:    * @param target the report target that receives generated events.
  62:    * @return the new layout controller instance representing the new state.
  63:    *
  64:    * @throws DataSourceException        if there was a problem reading data from
  65:    *                                    the datasource.
  66:    * @throws ReportProcessingException  if there was a general problem during
  67:    *                                    the report processing.
  68:    * @throws ReportDataFactoryException if a query failed.
  69:    */
  70:   public LayoutController advance(final ReportTarget target)
  71:       throws DataSourceException, ReportDataFactoryException,
  72:       ReportProcessingException
  73:   {
  74:     reportTarget.setTarget(target);
  75:     if (delegate != null)
  76:     {
  77:       try
  78:       {
  79:         final BufferingLayoutController bc = (BufferingLayoutController) clone();
  80:         bc.delegate = delegate.advance(reportTarget);
  81:         return bc;
  82:       }
  83:       finally
  84:       {
  85:         reportTarget.setTarget(null);
  86:       }
  87:     }
  88: 
  89:     // write all buffered changes to the real report target.
  90:     reportTarget.close(target);
  91:     if (getParent() == null)
  92:     {
  93:       final BufferingLayoutController bc = (BufferingLayoutController) clone();
  94:       bc.finished = true;
  95:       return bc;
  96:     }
  97: 
  98:     return joinWithParent();
  99:   }
 100: 
 101:   /**
 102:    * Joins the layout controller with the parent. This simply calls
 103:    * {@link #join(org.jfree.report.flow.FlowController)} on the parent. A join
 104:    * operation is necessary to propagate changes in the flow-controller to the
 105:    * parent for further processing.
 106:    *
 107:    * @return the joined parent.
 108:    * @throws IllegalStateException if this layout controller has no parent.
 109:    * @throws org.jfree.report.ReportProcessingException
 110:    * @throws org.jfree.report.ReportDataFactoryException
 111:    * @throws org.jfree.report.DataSourceException
 112:    */
 113:   protected LayoutController joinWithParent()
 114:       throws ReportProcessingException, ReportDataFactoryException,
 115:       DataSourceException
 116:   {
 117:     final LayoutController parent = getParent();
 118:     if (parent == null)
 119:     {
 120:       // skip to the next step ..
 121:       throw new IllegalStateException("There is no parent to join with. " +
 122:                                       "This should not happen in a sane environment!");
 123:     }
 124: 
 125:     return parent.join(getFlowController());
 126:   }
 127: 
 128: 
 129:   /**
 130:    * Initializes the layout controller. This method is called exactly once. It
 131:    * is the creators responsibility to call this method.
 132:    * <p/>
 133:    * Calling initialize after the first advance must result in a
 134:    * IllegalStateException.
 135:    *
 136:    * @param node           the currently processed object or layout node.
 137:    * @param flowController the current flow controller.
 138:    * @param parent         the parent layout controller that was responsible for
 139:    *                       instantiating this controller.
 140:    * @throws DataSourceException        if there was a problem reading data from
 141:    *                                    the datasource.
 142:    * @throws ReportProcessingException  if there was a general problem during
 143:    *                                    the report processing.
 144:    * @throws ReportDataFactoryException if a query failed.
 145:    */
 146:   public void initialize(final Object node, final FlowController flowController,
 147:                          final LayoutController parent)
 148:       throws DataSourceException, ReportDataFactoryException,
 149:       ReportProcessingException
 150:   {
 151:     super.initialize(node, flowController, parent);
 152:     delegate = getInitialDelegate();
 153:   }
 154: 
 155:   protected abstract LayoutController getInitialDelegate();
 156: 
 157:   public boolean isAdvanceable()
 158:   {
 159:     if (delegate == null)
 160:     {
 161:       return finished == false;
 162:     }
 163:     return delegate.isAdvanceable();
 164:   }
 165: 
 166:   /**
 167:    * Joins with a delegated process flow. This is generally called from a child
 168:    * flow and should *not* (I mean it!) be called from outside. If you do,
 169:    * you'll suffer.
 170:    *
 171:    * @param flowController the flow controller of the parent.
 172:    * @return the joined layout controller that incorperates all changes from
 173:    * the delegate.
 174:    */
 175:   public LayoutController join(final FlowController flowController)
 176:       throws ReportProcessingException, DataSourceException
 177:   {
 178:     // the delegation is finished, the element has returned.
 179:     final BufferingLayoutController bc = (BufferingLayoutController) clone();
 180:     bc.delegate = null;
 181:     return bc;
 182:   }
 183: 
 184:   public Object clone()
 185:   {
 186:     final BufferingLayoutController o = (BufferingLayoutController) super.clone();
 187:     o.reportTarget = (BufferedReportTarget) reportTarget.clone();
 188:     return o;
 189:   }
 190: }