From 194c471b1cf53892d5d1f0b0943b19a366221f91 Mon Sep 17 00:00:00 2001 From: William Victor Mote Date: Tue, 12 Aug 2003 06:18:43 +0000 Subject: [PATCH] 1. convert fo.FOTreeHandler to fire events when it completes a PageSequence or document object 2. move logic that starts layout from fo.FOTreeHandler to apps.Driver. 3. add logic to apps.Driver to handle the events fired from fo.FOTreeHandler 4. end result is that FOTreeHandler now allows other objects to handle page-sequence and document objects in a manner similar to the way SAX allows them to handle XML elements. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@196787 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/apps/Driver.java | 62 +++++++- .../org/apache/fop/extensions/Bookmarks.java | 2 +- .../org/apache/fop/fo/FOInputHandler.java | 6 +- src/java/org/apache/fop/fo/FOTreeHandler.java | 135 +++++++++--------- src/java/org/apache/fop/mif/MIFHandler.java | 4 +- .../apache/fop/rtf/renderer/RTFHandler.java | 4 +- 6 files changed, 139 insertions(+), 74 deletions(-) diff --git a/src/java/org/apache/fop/apps/Driver.java b/src/java/org/apache/fop/apps/Driver.java index b72b83307..129ab8e8e 100644 --- a/src/java/org/apache/fop/apps/Driver.java +++ b/src/java/org/apache/fop/apps/Driver.java @@ -51,11 +51,17 @@ package org.apache.fop.apps; // FOP +import org.apache.fop.area.AreaTree; +import org.apache.fop.area.AreaTreeModel; import org.apache.fop.fo.ElementMapping; import org.apache.fop.fo.FOTreeBuilder; import org.apache.fop.fo.FOUserAgent; import org.apache.fop.fo.FOInputHandler; import org.apache.fop.fo.FOTreeHandler; +import org.apache.fop.fo.FOTreeListener; +import org.apache.fop.fo.FOTreeEvent; +import org.apache.fop.area.Title; +import org.apache.fop.fo.pagination.PageSequence; import org.apache.fop.mif.MIFHandler; import org.apache.fop.render.Renderer; import org.apache.fop.render.awt.AWTRenderer; @@ -128,7 +134,7 @@ import java.io.OutputStream; * driver.render(parser, fileInputSource(args[0])); * */ -public class Driver implements LogEnabled { +public class Driver implements LogEnabled, FOTreeListener { /** * Render to PDF. OutputStream must be set @@ -221,6 +227,12 @@ public class Driver implements LogEnabled { private Logger log = null; private FOUserAgent userAgent = null; + /** + * The current AreaTree for the PageSequence being rendered. + */ + private AreaTree areaTree; + private AreaTreeModel atModel; + /** * Main constructor for the Driver class. */ @@ -528,15 +540,15 @@ public class Driver implements LogEnabled { // TODO: - do this stuff in a better way // PIJ: I guess the structure handler should be created by the renderer. if (rendererType == RENDER_MIF) { - foInputHandler = new MIFHandler(stream); + foInputHandler = new MIFHandler(this, stream); } else if (rendererType == RENDER_RTF) { - foInputHandler = new RTFHandler(stream); + foInputHandler = new RTFHandler(this, stream); } else { if (renderer == null) { throw new IllegalStateException( "Renderer not set when using standard foInputHandler"); } - foInputHandler = new FOTreeHandler(stream, renderer, true); + foInputHandler = new FOTreeHandler(this, stream, renderer, true); } foInputHandler.enableLogging(getLogger()); @@ -574,7 +586,19 @@ public class Driver implements LogEnabled { } parser.setContentHandler(getContentHandler()); try { + if (foInputHandler instanceof FOTreeHandler) { + FOTreeHandler foTreeHandler = (FOTreeHandler)foInputHandler; + foTreeHandler.addFOTreeListener(this); + this.areaTree = new AreaTree(); + this.atModel = AreaTree.createRenderPagesModel(renderer); + //this.atModel = new CachedRenderPagesModel(renderer); + areaTree.setTreeModel(atModel); + } parser.parse(source); + if (foInputHandler instanceof FOTreeHandler) { + FOTreeHandler foTreeHandler = (FOTreeHandler)foInputHandler; + foTreeHandler.removeFOTreeListener(this); + } } catch (SAXException e) { if (e.getException() instanceof FOPException) { // Undo exception tunneling. @@ -635,5 +659,35 @@ public class Driver implements LogEnabled { render(reader, source); } } + + public void foPageSequenceComplete (FOTreeEvent event) throws FOPException{ + PageSequence pageSeq = event.getPageSequence(); + Title title = null; + if (pageSeq.getTitleFO() != null) { + title = pageSeq.getTitleFO().getTitleArea(); + } + areaTree.startPageSequence(title); + pageSeq.format(areaTree); + } + + public void foDocumentComplete (FOTreeEvent event) throws SAXException{ + //processAreaTree(atModel); + try { + areaTree.endDocument(); + renderer.stopRenderer(); + } + catch (IOException ex) { + } + } + + /** + * Get the area tree for this layout handler. + * + * @return the area tree for this document + */ + public AreaTree getAreaTree() { + return areaTree; + } + } diff --git a/src/java/org/apache/fop/extensions/Bookmarks.java b/src/java/org/apache/fop/extensions/Bookmarks.java index 4fb6a6b86..0fa44f524 100644 --- a/src/java/org/apache/fop/extensions/Bookmarks.java +++ b/src/java/org/apache/fop/extensions/Bookmarks.java @@ -109,7 +109,7 @@ public class Bookmarks extends ExtensionObj { } // add data to area tree for resolving and handling if (foInputHandler instanceof FOTreeHandler) { - AreaTree at = ((FOTreeHandler)foInputHandler).getAreaTree(); + AreaTree at = ((FOTreeHandler)foInputHandler).driver.getAreaTree(); at.addTreeExtension(data); data.setAreaTree(at); } diff --git a/src/java/org/apache/fop/fo/FOInputHandler.java b/src/java/org/apache/fop/fo/FOInputHandler.java index 5aeb8bf6b..a3734e465 100644 --- a/src/java/org/apache/fop/fo/FOInputHandler.java +++ b/src/java/org/apache/fop/fo/FOInputHandler.java @@ -58,6 +58,7 @@ import java.util.HashSet; import org.apache.avalon.framework.logger.AbstractLogEnabled; // FOP +import org.apache.fop.apps.Driver; import org.apache.fop.apps.FOPException; import org.apache.fop.fo.flow.Block; import org.apache.fop.fo.flow.ExternalGraphic; @@ -93,10 +94,13 @@ public abstract class FOInputHandler extends AbstractLogEnabled { */ private Set idReferences = new HashSet(); + public Driver driver = null; + /** * Main constructor */ - public FOInputHandler() { + public FOInputHandler(Driver driver) { + this.driver = driver; } /** diff --git a/src/java/org/apache/fop/fo/FOTreeHandler.java b/src/java/org/apache/fop/fo/FOTreeHandler.java index b4d8cd464..67fe255d6 100644 --- a/src/java/org/apache/fop/fo/FOTreeHandler.java +++ b/src/java/org/apache/fop/fo/FOTreeHandler.java @@ -54,18 +54,17 @@ package org.apache.fop.fo; import java.io.IOException; import java.io.OutputStream; import java.util.List; +import java.util.HashSet; +import java.util.Iterator; // SAX import org.xml.sax.SAXException; // FOP +import org.apache.fop.apps.Driver; import org.apache.fop.apps.FOPException; -import org.apache.fop.area.AreaTree; -import org.apache.fop.area.AreaTreeModel; import org.apache.fop.area.StorePagesModel; -import org.apache.fop.area.Title; import org.apache.fop.area.TreeExt; -import org.apache.fop.fo.FOInputHandler; import org.apache.fop.fo.flow.Block; import org.apache.fop.fo.flow.ExternalGraphic; import org.apache.fop.fo.flow.InstreamForeignObject; @@ -134,10 +133,10 @@ public class FOTreeHandler extends FOInputHandler { private FontInfo fontInfo = new FontInfo(); /** - * The current AreaTree for the PageSequence being rendered. + * Collection of objects that have registered to be notified about + * FOTreeEvent firings. */ - private AreaTree areaTree; - private AreaTreeModel atModel; + private HashSet foTreeListeners = new HashSet(); /** * Main constructor @@ -146,27 +145,15 @@ public class FOTreeHandler extends FOInputHandler { * @param store if true then use the store pages model and keep the * area tree in memory */ - public FOTreeHandler(OutputStream outputStream, Renderer renderer, + public FOTreeHandler(Driver driver, OutputStream outputStream, Renderer renderer, boolean store) { + super(driver); if (collectStatistics) { runtime = Runtime.getRuntime(); } this.outputStream = outputStream; this.renderer = renderer; - this.areaTree = new AreaTree(); - this.atModel = AreaTree.createRenderPagesModel(renderer); - //this.atModel = new CachedRenderPagesModel(renderer); - areaTree.setTreeModel(atModel); - } - - /** - * Get the area tree for this layout handler. - * - * @return the area tree for this document - */ - public AreaTree getAreaTree() { - return areaTree; } /** @@ -205,13 +192,7 @@ public class FOTreeHandler extends FOInputHandler { * @throws SAXException if there is some error */ public void endDocument() throws SAXException { - try { - //processAreaTree(atModel); - areaTree.endDocument(); - renderer.stopRenderer(); - } catch (Exception e) { - throw new SAXException(e); - } + notifyDocumentComplete(); if (collectStatistics) { if (MEM_PROFILE_WITH_GC) { @@ -246,11 +227,6 @@ public class FOTreeHandler extends FOInputHandler { * @param pageSeq the page sequence starting */ public void startPageSequence(PageSequence pageSeq) { - Title title = null; - if (pageSeq.getTitleFO() != null) { - title = pageSeq.getTitleFO().getTitleArea(); - } - areaTree.startPageSequence(title); } /** @@ -275,7 +251,7 @@ public class FOTreeHandler extends FOInputHandler { getLogger().debug("Current heap size: " + (memoryNow / 1024L) + "Kb"); } } - pageSequence.format(areaTree); + notifyPageSequenceComplete(pageSequence); } /** @@ -497,44 +473,71 @@ public class FOTreeHandler extends FOInputHandler { } /** - * Process an area tree. - * If a store pages model is used this can read and send all the - * pages to the renderer. + * Get the font information for the layout handler. * - * @param model the store pages model - * @throws FOPException if there is an error - */ - private void processAreaTree(StorePagesModel model) throws FOPException { - int count = 0; - int seqc = model.getPageSequenceCount(); - while (count < seqc) { - Title title = model.getTitle(count); - renderer.startPageSequence(title); - int pagec = model.getPageCount(count); - for (int c = 0; c < pagec; c++) { - try { - renderer.renderPage(model.getPage(count, c)); - } catch (IOException ioex) { - throw new FOPException("I/O Error rendering page", - ioex); - } - } - count++; + * @return the font information + */ + public FontInfo getFontInfo() { + return this.fontInfo; + } + + /** + * Add an object to the collection of objects that should be notified about + * FOTreeEvent firings. + * @param listener the Object which should be notified + */ + public void addFOTreeListener (FOTreeListener listener) { + if (listener == null) { + return; } - List list = model.getEndExtensions(); - for (count = 0; count < list.size(); count++) { - TreeExt ext = (TreeExt)list.get(count); - renderer.renderExtension(ext); + foTreeListeners.add(listener); + } + + /** + * Remove an object from the collection of objects that should be notified + * about FOTreeEvent firings. + * @param listener the Object which should no longer be notified + */ + public void removeFOTreeListener (FOTreeListener listener) { + if (listener == null) { + return; } + foTreeListeners.remove(listener); } /** - * Get the font information for the layout handler. - * - * @return the font information + * Notify all objects in the foTreeListeners that a "Page Sequence Complete" + * FOTreeEvent has been fired. + * @param eventType integer indicating which type of event is created + * @param event the Event object that should be passed to the listeners */ - public FontInfo getFontInfo() { - return this.fontInfo; + private void notifyPageSequenceComplete(PageSequence pageSequence) + throws FOPException { + FOTreeEvent event = new FOTreeEvent(this); + event.setPageSequence(pageSequence); + Iterator iterator = foTreeListeners.iterator(); + FOTreeListener foTreeListenerItem = null; + while (iterator.hasNext()) { + foTreeListenerItem = (FOTreeListener)iterator.next(); + foTreeListenerItem.foPageSequenceComplete(event); + } } -} + /** + * Notify all objects in the foTreeListeners that a "Document Complete" + * FOTreeEvent has been fired. + * @param eventType integer indicating which type of event is created + * @param event the Event object that should be passed to the listeners + */ + private void notifyDocumentComplete() + throws SAXException { + FOTreeEvent event = new FOTreeEvent(this); + Iterator iterator = foTreeListeners.iterator(); + FOTreeListener foTreeListenerItem = null; + while (iterator.hasNext()) { + foTreeListenerItem = (FOTreeListener)iterator.next(); + foTreeListenerItem.foDocumentComplete(event); + } + } + +} diff --git a/src/java/org/apache/fop/mif/MIFHandler.java b/src/java/org/apache/fop/mif/MIFHandler.java index fe5989c4d..97f47c401 100644 --- a/src/java/org/apache/fop/mif/MIFHandler.java +++ b/src/java/org/apache/fop/mif/MIFHandler.java @@ -58,6 +58,7 @@ import java.io.OutputStream; import org.xml.sax.SAXException; // FOP +import org.apache.fop.apps.Driver; import org.apache.fop.fo.FOInputHandler; import org.apache.fop.fo.flow.Block; import org.apache.fop.fo.pagination.Flow; @@ -100,7 +101,8 @@ public class MIFHandler extends FOInputHandler { * Creates a new MIF handler on a given OutputStream. * @param os OutputStream to write to */ - public MIFHandler(OutputStream os) { + public MIFHandler(Driver driver, OutputStream os) { + super(driver); outStream = os; // use pdf fonts for now, this is only for resolving names org.apache.fop.render.pdf.FontSetup.setup(fontInfo, null); diff --git a/src/java/org/apache/fop/rtf/renderer/RTFHandler.java b/src/java/org/apache/fop/rtf/renderer/RTFHandler.java index 2f8c7309e..f952eb4dc 100644 --- a/src/java/org/apache/fop/rtf/renderer/RTFHandler.java +++ b/src/java/org/apache/fop/rtf/renderer/RTFHandler.java @@ -55,6 +55,7 @@ import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; +import org.apache.fop.apps.Driver; import org.apache.fop.apps.FOPException; import org.apache.fop.datatypes.ColorType; import org.apache.fop.fo.FOInputHandler; @@ -110,7 +111,8 @@ public class RTFHandler extends FOInputHandler { * Creates a new RTF structure handler. * @param os OutputStream to write to */ - public RTFHandler(OutputStream os) { + public RTFHandler(Driver driver, OutputStream os) { + super(driver); this.os = os; // use pdf fonts for now, this is only for resolving names org.apache.fop.render.pdf.FontSetup.setup(fontInfo, null); -- 2.39.5