KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > layoutmgr > AbstractLayoutManager


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 /* $Id: AbstractLayoutManager.java 453310 2006-10-05 18:44:15Z spepping $ */
19
20 package org.apache.fop.layoutmgr;
21
22 import org.apache.commons.logging.Log;
23 import org.apache.commons.logging.LogFactory;
24 import org.apache.fop.fo.FObj;
25 import org.apache.fop.fo.FONode;
26 import org.apache.fop.area.Area;
27 import org.apache.fop.area.PageViewport;
28 import org.apache.fop.fo.Constants;
29 import org.apache.fop.fo.flow.RetrieveMarker;
30
31 import java.util.LinkedList JavaDoc;
32 import java.util.List JavaDoc;
33 import java.util.ArrayList JavaDoc;
34 import java.util.ListIterator JavaDoc;
35 import java.util.Map JavaDoc;
36
37 /**
38  * The base class for most LayoutManagers.
39  */

40 public abstract class AbstractLayoutManager extends AbstractBaseLayoutManager
41     implements Constants {
42
43     /**
44      * logging instance
45      */

46     private static Log log = LogFactory.getLog(AbstractLayoutManager.class);
47
48     /** Parent LayoutManager for this LayoutManager */
49     protected LayoutManager parentLM = null;
50     /** List of child LayoutManagers */
51     protected List JavaDoc childLMs = null;
52     /** Iterator for child LayoutManagers */
53     protected ListIterator JavaDoc fobjIter = null;
54     /** Marker map for markers related to this LayoutManager */
55     protected Map JavaDoc markers = null;
56
57     /** True if this LayoutManager has handled all of its content. */
58     private boolean bFinished = false;
59     
60     /** child LM and child LM iterator during getNextKnuthElement phase */
61     protected LayoutManager curChildLM = null;
62     /** child LM and child LM iterator during getNextKnuthElement phase */
63     protected ListIterator JavaDoc childLMiter = null;
64     
65     private int lastGeneratedPosition = -1;
66     private int smallestPosNumberChecked = Integer.MAX_VALUE;
67
68     /**
69      * Abstract layout manager.
70      */

71     public AbstractLayoutManager() {
72     }
73
74     /**
75      * Abstract layout manager.
76      *
77      * @param fo the formatting object for this layout manager
78      */

79     public AbstractLayoutManager(FObj fo) {
80         super(fo);
81         if (fo == null) {
82             throw new IllegalStateException JavaDoc("Null formatting object found.");
83         }
84         markers = fo.getMarkers();
85         fobjIter = fo.getChildNodes();
86         childLMiter = new LMiter(this);
87     }
88
89     /** @see LayoutManager#setParent(LayoutManager) */
90     public void setParent(LayoutManager lm) {
91         this.parentLM = lm;
92     }
93
94     /** @see LayoutManager#getParent */
95     public LayoutManager getParent() {
96         return this.parentLM;
97     }
98
99     /** @see LayoutManager#initialize */
100     public void initialize() {
101         // Empty
102
}
103
104     /**
105      * Return currently active child LayoutManager or null if
106      * all children have finished layout.
107      * Note: child must implement LayoutManager! If it doesn't, skip it
108      * and print a warning.
109      * @return the current child LayoutManager
110      */

111     protected LayoutManager getChildLM() {
112         if (curChildLM != null && !curChildLM.isFinished()) {
113             return curChildLM;
114         }
115         while (childLMiter.hasNext()) {
116             curChildLM = (LayoutManager) childLMiter.next();
117             curChildLM.initialize();
118             return curChildLM;
119         }
120         return null;
121     }
122
123     /**
124      * Return indication if getChildLM will return another LM.
125      * @return true if another child LM is still available
126      */

127     protected boolean hasNextChildLM() {
128         return childLMiter.hasNext();
129     }
130
131     /**
132      * Reset the layoutmanager "iterator" so that it will start
133      * with the passed Position's generating LM
134      * on the next call to getChildLM.
135      * @param pos a Position returned by a child layout manager
136      * representing a potential break decision.
137      * If pos is null, then back up to the first child LM.
138      */

139     protected void reset(org.apache.fop.layoutmgr.Position pos) {
140         //if (lm == null) return;
141
LayoutManager lm = (pos != null) ? pos.getLM() : null;
142         if (curChildLM != lm) {
143             // ASSERT curChildLM == (LayoutManager)childLMiter.previous()
144
if (childLMiter.hasPrevious() && curChildLM
145                     != (LayoutManager) childLMiter.previous()) {
146                 //log.error("LMiter problem!");
147
}
148             while (curChildLM != lm && childLMiter.hasPrevious()) {
149                 curChildLM.resetPosition(null);
150                 curChildLM = (LayoutManager) childLMiter.previous();
151             }
152             // Otherwise next returns same object
153
childLMiter.next();
154         }
155         if (curChildLM != null) {
156             curChildLM.resetPosition(pos);
157         }
158         if (isFinished()) {
159             setFinished(false);
160         }
161     }
162
163     /** @see LayoutManager#resetPosition(Position) */
164     public void resetPosition(Position resetPos) {
165         // if (resetPos == null) {
166
// reset(null);
167
// }
168
}
169
170     /**
171      * Tell whether this LayoutManager has handled all of its content.
172      * @return True if there are no more break possibilities,
173      * ie. the last one returned represents the end of the content.
174      */

175     public boolean isFinished() {
176         return bFinished;
177     }
178
179     /**
180      * Set the flag indicating the LayoutManager has handled all of its content.
181      * @param fin the flag value to be set
182      */

183     public void setFinished(boolean fin) {
184         bFinished = fin;
185     }
186
187     /**
188      * @see org.apache.fop.layoutmgr.LayoutManager#addAreas(
189      * org.apache.fop.layoutmgr.PositionIterator
190      * , org.apache.fop.layoutmgr.LayoutContext)
191      */

192     public void addAreas(PositionIterator posIter, LayoutContext context) {
193     }
194
195     /**
196      * @see org.apache.fop.layoutmgr.LayoutManager#getNextKnuthElements(LayoutContext, int)
197      */

198     public LinkedList JavaDoc getNextKnuthElements(LayoutContext context,
199                                            int alignment) {
200         log.warn("null implementation of getNextKnuthElements() called!");
201         setFinished(true);
202         return null;
203     }
204
205     /**
206      * @see org.apache.fop.layoutmgr.LayoutManager#getChangedKnuthElements(List, int)
207      */

208     public LinkedList JavaDoc getChangedKnuthElements(List JavaDoc oldList,
209                                               int alignment) {
210         log.warn("null implementation of getChangeKnuthElement() called!");
211         return null;
212     }
213
214     /**
215      * Return an Area which can contain the passed childArea. The childArea
216      * may not yet have any content, but it has essential traits set.
217      * In general, if the LayoutManager already has an Area it simply returns
218      * it. Otherwise, it makes a new Area of the appropriate class.
219      * It gets a parent area for its area by calling its parent LM.
220      * Finally, based on the dimensions of the parent area, it initializes
221      * its own area. This includes setting the content IPD and the maximum
222      * BPD.
223      * @param childArea the child area for which the parent area is wanted
224      * @return the parent area for the given child
225      */

226     public Area getParentArea(Area childArea) {
227         return null;
228     }
229
230     /**
231      * Add a child area to the current area. If this causes the maximum
232      * dimension of the current area to be exceeded, the parent LM is called
233      * to add it.
234      * @param childArea the child area to be added
235      */

236     public void addChildArea(Area childArea) {
237     }
238
239     /**
240      * Create the LM instances for the children of the
241      * formatting object being handled by this LM.
242      * @param size the requested number of child LMs
243      * @return the list with the preloaded child LMs
244      */

245     protected List JavaDoc createChildLMs(int size) {
246         if (fobjIter == null) {
247             return null;
248         }
249         List JavaDoc newLMs = new ArrayList JavaDoc(size);
250         while (fobjIter.hasNext() && newLMs.size() < size ) {
251             Object JavaDoc theobj = fobjIter.next();
252             if (theobj instanceof FONode) {
253                 FONode foNode = (FONode) theobj;
254                 if (foNode instanceof RetrieveMarker) {
255                     foNode = getPSLM().resolveRetrieveMarker(
256                         (RetrieveMarker) foNode);
257                 }
258                 if (foNode != null) {
259                     getPSLM().getLayoutManagerMaker().
260                         makeLayoutManagers(foNode, newLMs);
261                 }
262             }
263         }
264         return newLMs;
265     }
266
267     /**
268      * @see org.apache.fop.layoutmgr.PageSequenceLayoutManager#getPSLM
269      */

270     public PageSequenceLayoutManager getPSLM() {
271         return parentLM.getPSLM();
272     }
273     
274     /**
275      * @see org.apache.fop.layoutmgr.PageSequenceLayoutManager#getCurrentPage
276      */

277     public Page getCurrentPage() {
278         return getPSLM().getCurrentPage();
279     }
280     
281     /** @return the current page viewport */
282     public PageViewport getCurrentPV() {
283         return getPSLM().getCurrentPage().getPageViewport();
284     }
285     
286     /**
287      * @see org.apache.fop.layoutmgr.LayoutManager#createNextChildLMs
288      */

289     public boolean createNextChildLMs(int pos) {
290         List JavaDoc newLMs = createChildLMs(pos + 1 - childLMs.size());
291         addChildLMs(newLMs);
292         return pos < childLMs.size();
293     }
294
295     /**
296      * @see org.apache.fop.layoutmgr.LayoutManager#getChildLMs
297      */

298     public List JavaDoc getChildLMs() {
299         if (childLMs == null) {
300             childLMs = new java.util.ArrayList JavaDoc(10);
301         }
302         return childLMs;
303     }
304
305     /**
306      * @see org.apache.fop.layoutmgr.LayoutManager#addChildLM
307      */

308     public void addChildLM(LayoutManager lm) {
309         if (lm == null) {
310             return;
311         }
312         lm.setParent(this);
313         if (childLMs == null) {
314             childLMs = new java.util.ArrayList JavaDoc(10);
315         }
316         childLMs.add(lm);
317         log.trace(this.getClass().getName()
318                   + ": Adding child LM " + lm.getClass().getName());
319     }
320
321     /**
322      * @see org.apache.fop.layoutmgr.LayoutManager#addChildLMs
323      */

324     public void addChildLMs(List JavaDoc newLMs) {
325         if (newLMs == null || newLMs.size() == 0) {
326             return;
327         }
328         ListIterator JavaDoc iter = newLMs.listIterator();
329         while (iter.hasNext()) {
330             LayoutManager lm = (LayoutManager) iter.next();
331             addChildLM(lm);
332         }
333     }
334
335     /**
336      * Adds a Position to the Position participating in the first|last determination by assigning
337      * it a unique position index.
338      * @param pos the Position
339      * @return the same Position but with a position index
340      */

341     public Position notifyPos(Position pos) {
342         if (pos.getIndex() >= 0) {
343             throw new IllegalStateException JavaDoc("Position already got its index");
344         }
345         lastGeneratedPosition++;
346         pos.setIndex(lastGeneratedPosition);
347         return pos;
348     }
349     
350     /**
351      * Indicates whether the given Position is the first area-generating Position of this LM.
352      * @param pos the Position (must be one with a position index)
353      * @return True if it is the first Position
354      */

355     public boolean isFirst(Position pos) {
356         //log.trace("isFirst() smallestPosNumberChecked=" + smallestPosNumberChecked + " " + pos);
357
if (pos.getIndex() < 0) {
358             throw new IllegalArgumentException JavaDoc("Only Positions with an index can be checked");
359         }
360         if (pos.getIndex() == this.smallestPosNumberChecked) {
361             return true;
362         } else if (pos.getIndex() < this.smallestPosNumberChecked) {
363             this.smallestPosNumberChecked = pos.getIndex();
364             return true;
365         } else {
366             return false;
367         }
368     }
369     
370     /**
371      * Indicates whether the given Position is the last area-generating Position of this LM.
372      * @param pos the Position (must be one with a position index)
373      * @return True if it is the last Position
374      */

375     public boolean isLast(Position pos) {
376         //log.trace("isLast() lastGenPos=" + lastGeneratedPosition + " " + pos);
377
if (pos.getIndex() < 0) {
378             throw new IllegalArgumentException JavaDoc("Only Positions with an index can be checked");
379         }
380         return (pos.getIndex() == this.lastGeneratedPosition
381                 && isFinished());
382     }
383
384     /**
385      * Transfers foreign attributes from the formatting object to the area.
386      * @param targetArea the area to set the attributes on
387      */

388     protected void transferForeignAttributes(Area targetArea) {
389         Map JavaDoc atts = getFObj().getForeignAttributes();
390         targetArea.setForeignAttributes(atts);
391     }
392 }
393
Popular Tags