001    /**
002     * ========================================
003     * JFreeReport : a free Java report library
004     * ========================================
005     *
006     * Project Info:  http://reporting.pentaho.org/
007     *
008     * (C) Copyright 2000-2007, by Object Refinery Limited, 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     * $Id: ContentElementLayoutController.java 3048 2007-07-28 18:02:42Z tmorgner $
027     * ------------
028     * (C) Copyright 2000-2005, by Object Refinery Limited.
029     * (C) Copyright 2005-2007, by Pentaho Corporation.
030     */
031    
032    package org.jfree.report.flow.layoutprocessor;
033    
034    import org.jfree.report.DataFlags;
035    import org.jfree.report.DataSourceException;
036    import org.jfree.report.ReportDataFactoryException;
037    import org.jfree.report.ReportProcessingException;
038    import org.jfree.report.data.DefaultDataFlags;
039    import org.jfree.report.expressions.Expression;
040    import org.jfree.report.flow.FlowController;
041    import org.jfree.report.flow.LayoutExpressionRuntime;
042    import org.jfree.report.flow.ReportContext;
043    import org.jfree.report.flow.ReportTarget;
044    import org.jfree.report.structure.ContentElement;
045    import org.jfree.report.structure.Node;
046    
047    /**
048     * Creation-Date: 24.11.2006, 15:06:56
049     *
050     * @author Thomas Morgner
051     */
052    public class ContentElementLayoutController extends ElementLayoutController
053    {
054      public ContentElementLayoutController()
055      {
056      }
057    
058      protected LayoutController processContent(final ReportTarget target)
059          throws DataSourceException, ReportProcessingException, ReportDataFactoryException
060      {
061    
062        final Node node = getElement();
063        final FlowController flowController = getFlowController();
064        final LayoutExpressionRuntime er =
065            LayoutControllerUtil.getExpressionRuntime(flowController, node);
066        final ContentElement element = (ContentElement) node;
067        final Expression ex = element.getValueExpression();
068        final Object value;
069    
070        if (ex != null)
071        {
072          try
073          {
074            ex.setRuntime(er);
075            value = ex.computeValue();
076          }
077          finally
078          {
079            ex.setRuntime(null);
080          }
081        }
082        else
083        {
084          value = null;
085        }
086    
087        // This should be a very rare case indeed ..
088        if (value instanceof DataFlags)
089        {
090          target.processContent((DataFlags) value);
091    
092          final ContentElementLayoutController derived = (ContentElementLayoutController) clone();
093          derived.setProcessingState(ElementLayoutController.FINISHING);
094          derived.setFlowController(flowController);
095          return derived;
096        }
097    
098        if (value instanceof Node)
099        {
100          // we explictly allow structural content here.
101          // As this might be a very expensive thing, if we
102          // keep it in a single state, we continue on a separate state.
103          final Node valueNode = (Node) value;
104          valueNode.updateParent(node.getParent());
105          final ReportContext reportContext = flowController.getReportContext();
106          final LayoutControllerFactory layoutControllerFactory =
107              reportContext.getLayoutControllerFactory();
108    
109          // actually, this is the same as if the element were a
110          // child element of a section. The only difference is
111          // that there can be only one child, and that there is no
112          // direct parent-child direction.
113    
114          final ContentElementLayoutController derived =
115              (ContentElementLayoutController) clone();
116          derived.setProcessingState(ElementLayoutController.WAITING_FOR_JOIN);
117          derived.setFlowController(flowController);
118    
119          return layoutControllerFactory.create
120              (flowController, valueNode, derived);
121        }
122    
123        if (ex != null)
124        {
125          target.processContent (new DefaultDataFlags(ex.getName(), value, true));
126        }
127    
128        final ContentElementLayoutController derived = (ContentElementLayoutController) clone();
129        derived.setProcessingState(ElementLayoutController.FINISHING);
130        derived.setFlowController(flowController);
131        return derived;
132      }
133    
134      /**
135       * Joins with a delegated process flow. This is generally called from a child
136       * flow and should *not* (I mean it!) be called from outside. If you do,
137       * you'll suffer.
138       *
139       * @param flowController the flow controller of the parent.
140       * @return the joined layout controller that incorperates all changes from
141       * the delegate.
142       */
143      public LayoutController join(final FlowController flowController)
144      {
145        final ContentElementLayoutController derived = (ContentElementLayoutController) clone();
146        derived.setProcessingState(ElementLayoutController.FINISHING);
147        derived.setFlowController(flowController);
148        return derived;
149      }
150    }