001    /**
002     * ===========================================
003     * LibLayout : a free Java layouting library
004     * ===========================================
005     *
006     * Project Info:  http://reporting.pentaho.org/liblayout/
007     *
008     * (C) Copyright 2006-2007, by 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: ChainingLayoutProcess.java 3524 2007-10-16 11:26:31Z tmorgner $
027     * ------------
028     * (C) Copyright 2006-2007, by Pentaho Corporation.
029     */
030    package org.jfree.layouting;
031    
032    import org.jfree.layouting.input.style.PseudoPage;
033    import org.jfree.layouting.input.style.values.CSSValue;
034    import org.jfree.layouting.layouter.context.DocumentContext;
035    import org.jfree.layouting.layouter.feed.InputFeed;
036    import org.jfree.layouting.layouter.style.resolver.StyleResolver;
037    import org.jfree.layouting.normalizer.content.NormalizationException;
038    import org.jfree.layouting.normalizer.content.Normalizer;
039    import org.jfree.layouting.output.ChainingOutputProcessor;
040    import org.jfree.layouting.output.OutputProcessor;
041    import org.jfree.layouting.output.OutputProcessorMetaData;
042    import org.jfree.resourceloader.ResourceManager;
043    import org.jfree.util.Log;
044    
045    /**
046     * Creation-Date: 16.06.2006, 14:42:57
047     *
048     * @author Thomas Morgner
049     */
050    public class ChainingLayoutProcess implements LayoutProcess
051    {
052      private static class ChainingLayoutProcessState implements LayoutProcessState
053      {
054        private LayoutProcessState chainedLayoutProcess;
055        private State inputFeed;
056    
057        private ChainingLayoutProcessState()
058        {
059        }
060    
061        public LayoutProcessState getChainedLayoutProcess()
062        {
063          return chainedLayoutProcess;
064        }
065    
066        public void setChainedLayoutProcess(final LayoutProcessState chainedLayoutProcess)
067        {
068          this.chainedLayoutProcess = chainedLayoutProcess;
069        }
070    
071        public State getInputFeed()
072        {
073          return inputFeed;
074        }
075    
076        public void setInputFeed(final State inputFeed)
077        {
078          this.inputFeed = inputFeed;
079        }
080    
081        public LayoutProcess restore(final OutputProcessor outputProcessor)
082            throws StateException
083        {
084    //      Log.error ("START ++++++++++++++++++++++++++++++++++++++++++++++++ ");
085    
086          final LayoutProcess root = chainedLayoutProcess.restore(outputProcessor);
087          final ChainingLayoutProcess proc = new ChainingLayoutProcess(root);
088          proc.outputProcessor = new ChainingOutputProcessor(outputProcessor);
089          if (inputFeed != null)
090          {
091            proc.inputFeed = (InputFeed) inputFeed.restore(proc);
092            if (proc.inputFeed == null)
093            {
094              throw new StateException();
095            }
096          }
097    //      Log.error ("DONE  ++++++++++++++++++++++++++++++++++++++++++++++++ ");
098    
099          return proc;
100        }
101      }
102    
103      private LayoutProcess chainedLayoutProcess;
104      private ChainingOutputProcessor outputProcessor;
105      private InputFeed inputFeed;
106    
107      public ChainingLayoutProcess(final LayoutProcess layoutProcess)
108      {
109        this.chainedLayoutProcess = layoutProcess;
110        this.outputProcessor = new ChainingOutputProcessor
111            (layoutProcess.getOutputProcessor());
112      }
113    
114      public InputFeed getInputFeed()
115      {
116        if (inputFeed == null)
117        {
118          inputFeed = outputProcessor.createInputFeed(this);
119        }
120        return inputFeed;
121      }
122    
123      public StyleResolver getStyleResolver()
124      {
125        return chainedLayoutProcess.getStyleResolver();
126      }
127    
128      /**
129       * The document context holds global information, like the used stylesheets.
130       * It also holds the caches for loading external contents.
131       *
132       * @return the document context.
133       */
134      public DocumentContext getDocumentContext()
135      {
136        return chainedLayoutProcess.getDocumentContext();
137      }
138    
139      public OutputProcessorMetaData getOutputMetaData()
140      {
141        return chainedLayoutProcess.getOutputMetaData();
142      }
143    
144      public OutputProcessor getOutputProcessor()
145      {
146        return outputProcessor;
147      }
148    
149      public ResourceManager getResourceManager()
150      {
151        return chainedLayoutProcess.getResourceManager();
152      }
153    
154      public void pageBreakEncountered(final CSSValue pageName,
155                                       final PseudoPage[] pseudoPages)
156          throws NormalizationException
157      {
158        getInputFeed().handlePageBreakEncountered(pageName, pseudoPages);
159      }
160    
161      /**
162       * A flag that indicates, whether one or more pagebreak have been encountered
163       * during the last operation. The flag does not necessarily state that the
164       * pagebreak(s) have been triggered by the last operation, it can as well be a
165       * delayed pagebreak indication due to caching or layouting effects (as it
166       * happens with pending or moved content).
167       *
168       * @return true, if a pagebreak as been encountered somewhere in the past,
169       *         false otherwise.
170       */
171      public boolean isPagebreakEncountered()
172      {
173        return getInputFeed().isPagebreakEncountered();
174      }
175    
176      public LayoutProcess getChainedLayoutProcess()
177      {
178        return chainedLayoutProcess;
179      }
180    
181      public void setChainedLayoutProcess(final LayoutProcess chainedLayoutProcess)
182      {
183        this.chainedLayoutProcess = chainedLayoutProcess;
184      }
185    
186      public LayoutProcessState saveState() throws StateException
187      {
188    //    Log.error ("SAVING  ++++++++++++++++++++++++++++++++++++++++++++++++ ");
189        final ChainingLayoutProcessState state = new ChainingLayoutProcessState();
190        state.setInputFeed(inputFeed.saveState());
191        state.setChainedLayoutProcess(chainedLayoutProcess.saveState());
192    //    Log.error ("DONE SAVING  +++++++++++++++++++++++++++++++++++++++++++ ");
193        return state;
194      }
195    
196      public Normalizer getNormalizer()
197      {
198        if (inputFeed == null)
199        {
200          throw new IllegalStateException
201              ("We cant have come that far without an input feed.");
202        }
203        return inputFeed.getCurrentNormalizer();
204      }
205    
206    
207    }