123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- /*
- * $Id$
- * Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
- * For details on use and redistribution please refer to the
- * LICENSE file included with these sources.
- */
-
- package org.apache.fop.fo;
-
- // FOP
- import org.apache.fop.apps.FOPException;
- import org.apache.fop.apps.StructureHandler;
- import org.apache.fop.fo.pagination.Root;
- import org.apache.fop.fo.pagination.PageSequence;
- import org.apache.fop.extensions.ExtensionObj;
-
- // Avalon
- import org.apache.avalon.framework.logger.Logger;
-
- // SAX
- import org.xml.sax.helpers.DefaultHandler;
- import org.xml.sax.SAXException;
- import org.xml.sax.InputSource;
- import org.xml.sax.Attributes;
-
- // Java
- import java.util.HashMap;
- import java.util.ArrayList;
- import java.io.IOException;
-
- /**
- * SAX Handler that builds the formatting object tree.
- *
- * Modified by Mark Lillywhite mark-fop@inomial.com. Now uses
- * StreamRenderer to automagically render the document as
- * soon as it receives a page-sequence end-tag. Also,
- * calls methods to set up and shut down the renderer at
- * the beginning and end of the FO document. Finally,
- * supresses adding the PageSequence object to the Root,
- * since it is parsed immediately.
- */
- public class FOTreeBuilder extends DefaultHandler {
-
- /**
- * table mapping element names to the makers of objects
- * representing formatting objects
- */
- protected HashMap fobjTable = new HashMap();
-
- protected ArrayList namespaces = new ArrayList();
-
- /**
- * current formatting object being handled
- */
- protected FONode currentFObj = null;
-
- /**
- * the root of the formatting object tree
- */
- protected FObj rootFObj = null;
-
- /**
- * set of names of formatting objects encountered but unknown
- */
- protected HashMap unknownFOs = new HashMap();
-
- /**
- *
- * The class that handles formatting and rendering to a stream
- * (mark-fop@inomial.com)
- */
- private StructureHandler structHandler;
- private FOUserAgent userAgent;
-
- public FOTreeBuilder() {}
-
- public Logger getLogger() {
- return userAgent.getLogger();
- }
-
- public void setUserAgent(FOUserAgent ua) {
- userAgent = ua;
- }
-
- public FOUserAgent getUserAgent() {
- return userAgent;
- }
-
-
- public void setStructHandler(StructureHandler sh) {
- this.structHandler = sh;
- }
-
- /**
- * add a mapping from element name to maker.
- *
- * @param namespaceURI namespace URI of formatting object element
- * @param localName local name of formatting object element
- * @param maker Maker for class representing formatting object
- */
- public void addMapping(String namespaceURI, HashMap table) {
- this.fobjTable.put(namespaceURI, table);
- this.namespaces.add(namespaceURI.intern());
- }
-
- /**
- * SAX Handler for characters
- */
- public void characters(char data[], int start, int length) {
- if(currentFObj != null) {
- currentFObj.addCharacters(data, start, start + length);
- }
- }
-
- /**
- * SAX Handler for the end of an element
- */
- public void endElement(String uri, String localName, String rawName)
- throws SAXException {
- currentFObj.end();
-
- currentFObj = currentFObj.getParent();
- }
-
- /**
- * SAX Handler for the start of the document
- */
- public void startDocument()
- throws SAXException {
- rootFObj = null; // allows FOTreeBuilder to be reused
- getLogger().info("building formatting object tree");
- structHandler.startDocument();
- }
-
- public void endDocument()
- throws SAXException {
- getLogger().info("Parsing of document complete, stopping renderer");
- structHandler.endDocument();
- }
-
- /**
- * SAX Handler for the start of an element
- */
- public void startElement(String uri, String localName, String rawName,
- Attributes attlist) throws SAXException {
- /* the formatting object started */
- FONode fobj;
-
- /* the maker for the formatting object started */
- ElementMapping.Maker fobjMaker = null;
-
- HashMap table = (HashMap)fobjTable.get(uri);
- if(table != null) {
- fobjMaker = (ElementMapping.Maker)table.get(localName);
- // try default
- if(fobjMaker == null) {
- fobjMaker = (ElementMapping.Maker)table.get(ElementMapping.DEFAULT);
- }
- }
-
- boolean foreignXML = false;
- if (fobjMaker == null) {
- String fullName = uri + "^" + localName;
- if (!this.unknownFOs.containsKey(fullName)) {
- this.unknownFOs.put(fullName, "");
- getLogger().warn("Unknown formatting object "
- + fullName);
- }
- if(namespaces.contains(uri.intern())) {
- // fall back
- fobjMaker = new Unknown.Maker();
- } else {
- fobjMaker = new UnknownXMLObj.Maker(uri);
- foreignXML = true;
- }
- }
-
- try {
- fobj = fobjMaker.make(currentFObj);
- fobj.setName(localName);
- // set the user agent for resolving user agent values
- fobj.setUserAgent(userAgent);
- // set the stream renderer so that appropriate
- // elements can add pages and handle resolving references
- fobj.setStructHandler(structHandler);
-
- fobj.handleAttrs(attlist);
- } catch (FOPException e) {
- throw new SAXException(e);
- }
-
- if (rootFObj == null) {
- if (!fobj.getName().equals("fo:root")) {
- throw new SAXException(new FOPException("Root element must"
- + " be fo:root, not "
- + fobj.getName()));
- }
- rootFObj = (FObj)fobj;
- } else {
- currentFObj.addChild(fobj);
- }
-
- currentFObj = fobj;
- }
-
- public void reset() {
- currentFObj = null;
- rootFObj = null;
- structHandler = null;
- }
-
- public boolean hasData() {
- return (rootFObj != null);
- }
-
- }
|