You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Driver.java 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. /*
  2. * $Id$
  3. * ============================================================================
  4. * The Apache Software License, Version 1.1
  5. * ============================================================================
  6. *
  7. * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modifica-
  10. * tion, are permitted provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice,
  13. * this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright notice,
  16. * this list of conditions and the following disclaimer in the documentation
  17. * and/or other materials provided with the distribution.
  18. *
  19. * 3. The end-user documentation included with the redistribution, if any, must
  20. * include the following acknowledgment: "This product includes software
  21. * developed by the Apache Software Foundation (http://www.apache.org/)."
  22. * Alternately, this acknowledgment may appear in the software itself, if
  23. * and wherever such third-party acknowledgments normally appear.
  24. *
  25. * 4. The names "FOP" and "Apache Software Foundation" must not be used to
  26. * endorse or promote products derived from this software without prior
  27. * written permission. For written permission, please contact
  28. * apache@apache.org.
  29. *
  30. * 5. Products derived from this software may not be called "Apache", nor may
  31. * "Apache" appear in their name, without prior written permission of the
  32. * Apache Software Foundation.
  33. *
  34. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
  35. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  36. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  37. * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  38. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
  39. * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  40. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  43. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44. * ============================================================================
  45. *
  46. * This software consists of voluntary contributions made by many individuals
  47. * on behalf of the Apache Software Foundation and was originally created by
  48. * James Tauber <jtauber@jtauber.com>. For more information on the Apache
  49. * Software Foundation, please see <http://www.apache.org/>.
  50. */
  51. package org.apache.fop.apps;
  52. // FOP
  53. import org.apache.fop.area.AreaTree;
  54. import org.apache.fop.area.AreaTreeModel;
  55. import org.apache.fop.fo.ElementMapping;
  56. import org.apache.fop.fo.FOTreeBuilder;
  57. import org.apache.fop.fo.FOUserAgent;
  58. import org.apache.fop.fo.FOInputHandler;
  59. import org.apache.fop.fo.FOTreeHandler;
  60. import org.apache.fop.fo.FOTreeListener;
  61. import org.apache.fop.fo.FOTreeEvent;
  62. import org.apache.fop.area.Title;
  63. import org.apache.fop.fo.pagination.PageSequence;
  64. import org.apache.fop.mif.MIFHandler;
  65. import org.apache.fop.render.Renderer;
  66. import org.apache.fop.render.awt.AWTRenderer;
  67. import org.apache.fop.rtf.renderer.RTFHandler;
  68. import org.apache.fop.tools.DocumentInputSource;
  69. import org.apache.fop.tools.DocumentReader;
  70. // Avalon
  71. import org.apache.avalon.framework.logger.ConsoleLogger;
  72. import org.apache.avalon.framework.logger.LogEnabled;
  73. import org.apache.avalon.framework.logger.Logger;
  74. // DOM
  75. import org.w3c.dom.Document;
  76. // SAX
  77. import org.xml.sax.ContentHandler;
  78. import org.xml.sax.InputSource;
  79. import org.xml.sax.SAXException;
  80. import org.xml.sax.XMLReader;
  81. // Java
  82. import java.io.IOException;
  83. import java.io.OutputStream;
  84. /**
  85. * Primary class that drives overall FOP process.
  86. * <P>
  87. * The simplest way to use this is to instantiate it with the
  88. * InputSource and OutputStream, then set the renderer desired, and
  89. * calling run();
  90. * <P>
  91. * Here is an example use of Driver which outputs PDF:
  92. *
  93. * <PRE>
  94. * Driver driver = new Driver(new InputSource (args[0]),
  95. * new FileOutputStream(args[1]));
  96. * driver.enableLogging(myLogger); //optional
  97. * driver.setRenderer(RENDER_PDF);
  98. * driver.run();
  99. * </PRE>
  100. * If neccessary, calling classes can call into the lower level
  101. * methods to setup and
  102. * render. Methods can be called to set the
  103. * Renderer to use, the (possibly multiple) ElementMapping(s) to
  104. * use and the OutputStream to use to output the results of the
  105. * rendering (where applicable). In the case of the Renderer and
  106. * ElementMapping(s), the Driver may be supplied either with the
  107. * object itself, or the name of the class, in which case Driver will
  108. * instantiate the class itself. The advantage of the latter is it
  109. * enables runtime determination of Renderer and ElementMapping(s).
  110. * <P>
  111. * Once the Driver is set up, the render method
  112. * is called. Depending on whether DOM or SAX is being used, the
  113. * invocation of the method is either render(Document) or
  114. * buildFOTree(Parser, InputSource) respectively.
  115. * <P>
  116. * A third possibility may be used to build the FO Tree, namely
  117. * calling getContentHandler() and firing the SAX events yourself.
  118. * <P>
  119. * Once the FO Tree is built, the format() and render() methods may be
  120. * called in that order.
  121. * <P>
  122. * Here is an example use of Driver which outputs to AWT:
  123. *
  124. * <PRE>
  125. * Driver driver = new Driver();
  126. * driver.enableLogging(myLogger); //optional
  127. * driver.setRenderer(new org.apache.fop.render.awt.AWTRenderer(translator));
  128. * driver.render(parser, fileInputSource(args[0]));
  129. * </PRE>
  130. */
  131. public class Driver implements LogEnabled, FOTreeListener {
  132. /**
  133. * Render to PDF. OutputStream must be set
  134. */
  135. public static final int RENDER_PDF = 1;
  136. /**
  137. * Render to a GUI window. No OutputStream neccessary
  138. */
  139. public static final int RENDER_AWT = 2;
  140. /**
  141. * Render to MIF. OutputStream must be set
  142. */
  143. public static final int RENDER_MIF = 3;
  144. /**
  145. * Render to XML. OutputStream must be set
  146. */
  147. public static final int RENDER_XML = 4;
  148. /**
  149. * Render to PRINT. No OutputStream neccessary
  150. */
  151. public static final int RENDER_PRINT = 5;
  152. /**
  153. * Render to PCL. OutputStream must be set
  154. */
  155. public static final int RENDER_PCL = 6;
  156. /**
  157. * Render to Postscript. OutputStream must be set
  158. */
  159. public static final int RENDER_PS = 7;
  160. /**
  161. * Render to Text. OutputStream must be set
  162. */
  163. public static final int RENDER_TXT = 8;
  164. /**
  165. * Render to SVG. OutputStream must be set
  166. */
  167. public static final int RENDER_SVG = 9;
  168. /**
  169. * Render to RTF. OutputStream must be set
  170. */
  171. public static final int RENDER_RTF = 10;
  172. /**
  173. * the FO tree builder
  174. */
  175. private FOTreeBuilder treeBuilder;
  176. /**
  177. * the renderer type code given by setRenderer
  178. */
  179. private int rendererType;
  180. /**
  181. * the renderer to use to output the area tree
  182. */
  183. private Renderer renderer;
  184. /**
  185. * the SAX ContentHandler
  186. */
  187. private FOInputHandler foInputHandler;
  188. /**
  189. * the source of the FO file
  190. */
  191. private InputSource source;
  192. /**
  193. * the stream to use to output the results of the renderer
  194. */
  195. private OutputStream stream;
  196. /**
  197. * The XML parser to use when building the FO tree
  198. */
  199. private XMLReader reader;
  200. /**
  201. * the system resources that FOP will use
  202. */
  203. private Logger log = null;
  204. private FOUserAgent userAgent = null;
  205. /**
  206. * The current AreaTree for the PageSequence being rendered.
  207. */
  208. private AreaTree areaTree;
  209. private AreaTreeModel atModel;
  210. /**
  211. * Main constructor for the Driver class.
  212. */
  213. public Driver() {
  214. stream = null;
  215. }
  216. /**
  217. * Convenience constructor for directly setting input and output.
  218. * @param source InputSource to take the XSL-FO input from
  219. * @param stream Target output stream
  220. */
  221. public Driver(InputSource source, OutputStream stream) {
  222. this();
  223. this.source = source;
  224. this.stream = stream;
  225. }
  226. private boolean isInitialized() {
  227. return (treeBuilder != null);
  228. }
  229. /**
  230. * Initializes the Driver object.
  231. */
  232. public void initialize() {
  233. if (isInitialized()) {
  234. throw new IllegalStateException("Driver already initialized");
  235. }
  236. treeBuilder = new FOTreeBuilder();
  237. treeBuilder.setUserAgent(getUserAgent());
  238. }
  239. /**
  240. * Optionally sets the FOUserAgent instance for FOP to use. The Driver
  241. * class sets up its own FOUserAgent if none is set through this method.
  242. * @param agent FOUserAgent to use
  243. */
  244. public void setUserAgent(FOUserAgent agent) {
  245. userAgent = agent;
  246. }
  247. private FOUserAgent getUserAgent() {
  248. if (userAgent == null) {
  249. userAgent = new FOUserAgent();
  250. userAgent.enableLogging(getLogger());
  251. userAgent.setBaseURL("");
  252. }
  253. return userAgent;
  254. }
  255. /**
  256. * Provide the Driver instance with a logger. More information on Avalon
  257. * logging can be found at the
  258. * <a href="http://avalon.apache.org">Avalon site</a>.
  259. *
  260. * @param log the logger. Must not be <code>null</code>.
  261. * @see org.apache.avalon.framework.logger.LogEnabled#enableLogging(Logger)
  262. */
  263. public void enableLogging(Logger log) {
  264. if (this.log == null) {
  265. this.log = log;
  266. } else {
  267. getLogger().warn("Logger is already set! Won't use the new logger.");
  268. }
  269. }
  270. /**
  271. * Provide the Driver instance with a logger.
  272. * @param log the logger. Must not be <code>null</code>.
  273. * @deprecated Use #enableLogging(Logger) instead.
  274. */
  275. public void setLogger(Logger log) {
  276. enableLogging(log);
  277. }
  278. /**
  279. * Returns the logger for use by FOP.
  280. * @return the logger
  281. * @see #enableLogging(Logger)
  282. */
  283. protected Logger getLogger() {
  284. if (this.log == null) {
  285. this.log = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
  286. this.log.error("Logger not set. Using ConsoleLogger as default.");
  287. }
  288. return this.log;
  289. }
  290. /**
  291. * Resets the Driver so it can be reused. Property and element
  292. * mappings are reset to defaults.
  293. * The output stream is cleared. The renderer is cleared.
  294. */
  295. public synchronized void reset() {
  296. source = null;
  297. stream = null;
  298. reader = null;
  299. if (treeBuilder != null) {
  300. treeBuilder.reset();
  301. }
  302. }
  303. /**
  304. * Indicates whether FOP has already received input data.
  305. * @return true, if input data was received
  306. */
  307. public boolean hasData() {
  308. return (treeBuilder.hasData());
  309. }
  310. /**
  311. * Set the OutputStream to use to output the result of the Renderer
  312. * (if applicable)
  313. * @param stream the stream to output the result of rendering to
  314. */
  315. public void setOutputStream(OutputStream stream) {
  316. this.stream = stream;
  317. }
  318. private void validateOutputStream() {
  319. if (this.stream == null) {
  320. throw new IllegalStateException("OutputStream has not been set");
  321. }
  322. }
  323. /**
  324. * Set the source for the FO document. This can be a normal SAX
  325. * InputSource, or an DocumentInputSource containing a DOM document.
  326. * @see DocumentInputSource
  327. */
  328. public void setInputSource(InputSource source) {
  329. this.source = source;
  330. }
  331. /**
  332. * Sets the reader used when reading in the source. If not set,
  333. * this defaults to a basic SAX parser.
  334. * @param reader the reader to use.
  335. */
  336. public void setXMLReader(XMLReader reader) {
  337. this.reader = reader;
  338. }
  339. /**
  340. * Shortcut to set the rendering type to use. Must be one of
  341. * <ul>
  342. * <li>RENDER_PDF</li>
  343. * <li>RENDER_AWT</li>
  344. * <li>RENDER_PRINT</li>
  345. * <li>RENDER_MIF</li>
  346. * <li>RENDER_XML</li>
  347. * <li>RENDER_PCL</li>
  348. * <li>RENDER_PS</li>
  349. * <li>RENDER_TXT</li>
  350. * <li>RENDER_SVG</li>
  351. * <li>RENDER_RTF</li>
  352. * </ul>
  353. * @param renderer the type of renderer to use
  354. * @throws IllegalArgumentException if an unsupported renderer type was required.
  355. */
  356. public void setRenderer(int renderer) throws IllegalArgumentException {
  357. rendererType = renderer;
  358. switch (renderer) {
  359. case RENDER_PDF:
  360. setRenderer("org.apache.fop.render.pdf.PDFRenderer");
  361. break;
  362. case RENDER_AWT:
  363. throw new IllegalArgumentException("Use renderer form of setRenderer() for AWT");
  364. case RENDER_PRINT:
  365. setRenderer("org.apache.fop.render.awt.AWTPrintRenderer");
  366. break;
  367. case RENDER_PCL:
  368. setRenderer("org.apache.fop.render.pcl.PCLRenderer");
  369. break;
  370. case RENDER_PS:
  371. setRenderer("org.apache.fop.render.ps.PSRenderer");
  372. break;
  373. case RENDER_TXT:
  374. setRenderer("org.apache.fop.render.txt.TXTRenderer()");
  375. break;
  376. case RENDER_MIF:
  377. //foInputHandler will be set later
  378. break;
  379. case RENDER_XML:
  380. setRenderer("org.apache.fop.render.xml.XMLRenderer");
  381. break;
  382. case RENDER_SVG:
  383. setRenderer("org.apache.fop.render.svg.SVGRenderer");
  384. break;
  385. case RENDER_RTF:
  386. //foInputHandler will be set later
  387. break;
  388. default:
  389. throw new IllegalArgumentException("Unknown renderer type");
  390. }
  391. }
  392. /**
  393. * Set the Renderer to use.
  394. * @param renderer the renderer instance to use (Note: Logger must be set at this point)
  395. */
  396. public void setRenderer(Renderer renderer) {
  397. // AWTStarter calls this function directly
  398. if (renderer instanceof AWTRenderer) {
  399. rendererType = RENDER_AWT;
  400. }
  401. renderer.setProducer(Version.getVersion());
  402. renderer.setUserAgent(getUserAgent());
  403. this.renderer = renderer;
  404. }
  405. /**
  406. * Returns the currently active renderer.
  407. * @return the renderer
  408. */
  409. public Renderer getRenderer() {
  410. return renderer;
  411. }
  412. /**
  413. * Sets the renderer.
  414. * @param rendererClassName the fully qualified classname of the renderer
  415. * class to use.
  416. * @param version version number
  417. * @deprecated use renderer.setProducer(version) + setRenderer(renderer) or
  418. * just setRenderer(rendererType) which will use the default producer string.
  419. * @see #setRenderer(int)
  420. * @see #setRenderer(Renderer)
  421. */
  422. public void setRenderer(String rendererClassName, String version) {
  423. setRenderer(rendererClassName);
  424. }
  425. /**
  426. * Set the class name of the Renderer to use as well as the
  427. * producer string for those renderers that can make use of it.
  428. * @param rendererClassName classname of the renderer to use such as
  429. * "org.apache.fop.render.pdf.PDFRenderer"
  430. * @exception IllegalArgumentException if the classname was invalid.
  431. * @see #setRenderer(int)
  432. */
  433. public void setRenderer(String rendererClassName)
  434. throws IllegalArgumentException {
  435. try {
  436. renderer =
  437. (Renderer)Class.forName(rendererClassName).newInstance();
  438. if (renderer instanceof LogEnabled) {
  439. ((LogEnabled)renderer).enableLogging(getLogger());
  440. }
  441. renderer.setProducer(Version.getVersion());
  442. renderer.setUserAgent(getUserAgent());
  443. } catch (ClassNotFoundException e) {
  444. throw new IllegalArgumentException("Could not find "
  445. + rendererClassName);
  446. } catch (InstantiationException e) {
  447. throw new IllegalArgumentException("Could not instantiate "
  448. + rendererClassName);
  449. } catch (IllegalAccessException e) {
  450. throw new IllegalArgumentException("Could not access "
  451. + rendererClassName);
  452. } catch (ClassCastException e) {
  453. throw new IllegalArgumentException(rendererClassName
  454. + " is not a renderer");
  455. }
  456. }
  457. /**
  458. * Add the given element mapping.
  459. * An element mapping maps element names to Java classes.
  460. *
  461. * @param mapping the element mappingto add
  462. */
  463. public void addElementMapping(ElementMapping mapping) {
  464. treeBuilder.addElementMapping(mapping);
  465. }
  466. /**
  467. * Add the element mapping with the given class name.
  468. * @param mappingClassName the class name representing the element mapping.
  469. */
  470. public void addElementMapping(String mappingClassName) {
  471. treeBuilder.addElementMapping(mappingClassName);
  472. }
  473. /**
  474. * Determines which SAX ContentHandler is appropriate for the rendererType.
  475. * Structure renderers (e.g. MIF & RTF) each have a specialized
  476. * ContentHandler that directly place data into the output stream. Layout
  477. * renderers (e.g. PDF & PostScript) use a ContentHandler that builds an FO
  478. * Tree.
  479. * @return a SAX ContentHandler for handling the SAX events.
  480. */
  481. public ContentHandler getContentHandler() {
  482. if (!isInitialized()) {
  483. initialize();
  484. }
  485. if (rendererType != RENDER_PRINT && rendererType != RENDER_AWT) {
  486. validateOutputStream();
  487. }
  488. // TODO: - do this stuff in a better way
  489. // PIJ: I guess the structure handler should be created by the renderer.
  490. if (rendererType == RENDER_MIF) {
  491. foInputHandler = new MIFHandler(this, stream);
  492. } else if (rendererType == RENDER_RTF) {
  493. foInputHandler = new RTFHandler(this, stream);
  494. } else {
  495. if (renderer == null) {
  496. throw new IllegalStateException(
  497. "Renderer not set when using standard foInputHandler");
  498. }
  499. foInputHandler = new FOTreeHandler(this, stream, renderer, true);
  500. }
  501. foInputHandler.enableLogging(getLogger());
  502. treeBuilder.setUserAgent(getUserAgent());
  503. treeBuilder.setFOInputHandler(foInputHandler);
  504. return treeBuilder;
  505. }
  506. /**
  507. * Render the FO document read by a SAX Parser from an InputHandler
  508. * @param inputHandler the input handler containing the source and
  509. * parser information.
  510. * @throws FOPException if anything goes wrong.
  511. */
  512. public synchronized void render(InputHandler inputHandler)
  513. throws FOPException {
  514. XMLReader parser = inputHandler.getParser();
  515. render(parser, inputHandler.getInputSource());
  516. }
  517. /**
  518. * This is the main render() method. The other render() methods are for
  519. * convenience, and normalize to this form, then run this.
  520. * Renders the FO document read by a SAX Parser from an InputSource.
  521. * @param parser the SAX parser.
  522. * @param source the input source the parser reads from.
  523. * @throws FOPException if anything goes wrong.
  524. */
  525. public synchronized void render(XMLReader parser, InputSource source)
  526. throws FOPException {
  527. if (!isInitialized()) {
  528. initialize();
  529. }
  530. parser.setContentHandler(getContentHandler());
  531. try {
  532. if (foInputHandler instanceof FOTreeHandler) {
  533. FOTreeHandler foTreeHandler = (FOTreeHandler)foInputHandler;
  534. foTreeHandler.addFOTreeListener(this);
  535. this.areaTree = new AreaTree();
  536. this.atModel = AreaTree.createRenderPagesModel(renderer);
  537. //this.atModel = new CachedRenderPagesModel(renderer);
  538. areaTree.setTreeModel(atModel);
  539. }
  540. parser.parse(source);
  541. if (foInputHandler instanceof FOTreeHandler) {
  542. FOTreeHandler foTreeHandler = (FOTreeHandler)foInputHandler;
  543. foTreeHandler.removeFOTreeListener(this);
  544. }
  545. } catch (SAXException e) {
  546. if (e.getException() instanceof FOPException) {
  547. // Undo exception tunneling.
  548. throw (FOPException)e.getException();
  549. } else {
  550. throw new FOPException(e);
  551. }
  552. } catch (IOException e) {
  553. throw new FOPException(e);
  554. }
  555. }
  556. /**
  557. * This method overloads the main render() method, adding the convenience
  558. * of using a DOM Document as input.
  559. * @see render(XMLReader, InputSource)
  560. * @param document the DOM document to read from
  561. * @throws FOPException if anything goes wrong.
  562. */
  563. public synchronized void render(Document document)
  564. throws FOPException {
  565. DocumentInputSource source = new DocumentInputSource(document);
  566. DocumentReader reader = new DocumentReader();
  567. render(reader, source);
  568. }
  569. /**
  570. * Runs the formatting and renderering process using the previously set
  571. * parser, input source, renderer and output stream.
  572. * If the renderer was not set, default to PDF.
  573. * If no parser was set, and the input source is not a dom document,
  574. * get a default SAX parser.
  575. * @throws IOException in case of IO errors.
  576. * @throws FOPException if anything else goes wrong.
  577. */
  578. public synchronized void run() throws IOException, FOPException {
  579. if (!isInitialized()) {
  580. initialize();
  581. }
  582. if (renderer == null) {
  583. setRenderer(RENDER_PDF);
  584. }
  585. if (source == null) {
  586. throw new FOPException("InputSource is not set.");
  587. }
  588. if (reader == null) {
  589. if (!(source instanceof DocumentInputSource)) {
  590. reader = FOFileHandler.createParser();
  591. }
  592. }
  593. if (source instanceof DocumentInputSource) {
  594. render(((DocumentInputSource)source).getDocument());
  595. } else {
  596. render(reader, source);
  597. }
  598. }
  599. public void foPageSequenceComplete (FOTreeEvent event) throws FOPException{
  600. PageSequence pageSeq = event.getPageSequence();
  601. Title title = null;
  602. if (pageSeq.getTitleFO() != null) {
  603. title = pageSeq.getTitleFO().getTitleArea();
  604. }
  605. areaTree.startPageSequence(title);
  606. pageSeq.format(areaTree);
  607. }
  608. public void foDocumentComplete (FOTreeEvent event) throws SAXException{
  609. //processAreaTree(atModel);
  610. try {
  611. areaTree.endDocument();
  612. renderer.stopRenderer();
  613. }
  614. catch (IOException ex) {
  615. }
  616. }
  617. /**
  618. * Get the area tree for this layout handler.
  619. *
  620. * @return the area tree for this document
  621. */
  622. public AreaTree getAreaTree() {
  623. return areaTree;
  624. }
  625. }