]> source.dussan.org Git - xmlgraphics-fop.git/commitdiff
1.) Moved DocumentInputSource & DocumentReader to apps package, made private
authorGlen Mazza <gmazza@apache.org>
Mon, 5 Jul 2004 23:47:56 +0000 (23:47 +0000)
committerGlen Mazza <gmazza@apache.org>
Mon, 5 Jul 2004 23:47:56 +0000 (23:47 +0000)
to package.

2.) Added validity checking to fo:static-content.

3.) Bug with uninitialized FOUserAgent in Driver fixed (this will probably
need more analysis later.)

git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@197753 13f79535-47bb-0310-9956-ffa450edef68

src/java/org/apache/fop/apps/DocumentInputSource.java [new file with mode: 0644]
src/java/org/apache/fop/apps/DocumentReader.java [new file with mode: 0644]
src/java/org/apache/fop/apps/Driver.java
src/java/org/apache/fop/fo/pagination/Flow.java
src/java/org/apache/fop/fo/pagination/StaticContent.java
src/java/org/apache/fop/tools/DocumentInputSource.java [deleted file]
src/java/org/apache/fop/tools/DocumentReader.java [deleted file]

diff --git a/src/java/org/apache/fop/apps/DocumentInputSource.java b/src/java/org/apache/fop/apps/DocumentInputSource.java
new file mode 100644 (file)
index 0000000..cff1369
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+package org.apache.fop.apps;
+
+import org.w3c.dom.Document;
+import org.xml.sax.InputSource;
+
+/**
+ * This is an InputSource to be used with DocumentReader.
+ *
+ * @author Kelly A Campbell
+ */
+class DocumentInputSource extends InputSource {
+    
+    private Document document;
+
+    /**
+     * Default constructor.
+     */
+    public DocumentInputSource() {
+        super();
+    }
+
+    /**
+     * Main constructor
+     * @param document the DOM document to use as input
+     */
+    public DocumentInputSource(Document document) {
+        this();
+        setDocument(document);
+    }
+
+    /**
+     * Returns the input document.
+     * @return the input DOM document.
+     */
+    public Document getDocument() {
+        return this.document;
+    }
+
+    /**
+     * Sets the input document.
+     * @param document the DOM document to use as input
+     */
+    public void setDocument(Document document) {
+        this.document = document;
+    }
+
+}
+
+
diff --git a/src/java/org/apache/fop/apps/DocumentReader.java b/src/java/org/apache/fop/apps/DocumentReader.java
new file mode 100644 (file)
index 0000000..6246761
--- /dev/null
@@ -0,0 +1,519 @@
+/*
+ * Copyright 1999-2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* $Id$ */
+package org.apache.fop.apps;
+
+import java.io.IOException;
+
+// DOM
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+// SAX
+import org.xml.sax.ContentHandler;
+import org.xml.sax.DTDHandler;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXNotRecognizedException;
+import org.xml.sax.SAXNotSupportedException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ * This presents a DOM as an XMLReader to make it easy to use a Document
+ * with a SAX-based implementation.
+ *
+ * @author Kelly A Campbell
+ *
+ */
+
+class DocumentReader implements XMLReader {
+
+    // //////////////////////////////////////////////////////////////////
+    // Configuration.
+    // //////////////////////////////////////////////////////////////////
+    private boolean namespaces = true;
+    private boolean namespacePrefixes = true;
+
+
+    /**
+     * Look up the value of a feature.
+     *
+     * <p>The feature name is any fully-qualified URI.  It is
+     * possible for an XMLReader to recognize a feature name but
+     * to be unable to return its value; this is especially true
+     * in the case of an adapter for a SAX1 Parser, which has
+     * no way of knowing whether the underlying parser is
+     * performing validation or expanding external entities.</p>
+     *
+     * <p>All XMLReaders are required to recognize the
+     * http://xml.org/sax/features/namespaces and the
+     * http://xml.org/sax/features/namespace-prefixes feature names.</p>
+     *
+     * <p>Some feature values may be available only in specific
+     * contexts, such as before, during, or after a parse.</p>
+     *
+     * <p>Typical usage is something like this:</p>
+     *
+     * <pre>
+     * XMLReader r = new MySAXDriver();
+     *
+     * // try to activate validation
+     * try {
+     * r.setFeature("http://xml.org/sax/features/validation", true);
+     * } catch (SAXException e) {
+     * System.err.println("Cannot activate validation.");
+     * }
+     *
+     * // register event handlers
+     * r.setContentHandler(new MyContentHandler());
+     * r.setErrorHandler(new MyErrorHandler());
+     *
+     * // parse the first document
+     * try {
+     * r.parse("http://www.foo.com/mydoc.xml");
+     * } catch (IOException e) {
+     * System.err.println("I/O exception reading XML document");
+     * } catch (SAXException e) {
+     * System.err.println("XML exception reading document.");
+     * }
+     * </pre>
+     *
+     * <p>Implementors are free (and encouraged) to invent their own features,
+     * using names built on their own URIs.</p>
+     *
+     * @param name The feature name, which is a fully-qualified URI.
+     * @return The current state of the feature (true or false).
+     * @exception SAXNotRecognizedException When the
+     * XMLReader does not recognize the feature name.
+     * @exception SAXNotSupportedException When the
+     * XMLReader recognizes the feature name but
+     * cannot determine its value at this time.
+     * @see #setFeature
+     */
+    public boolean getFeature(String name)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        if ("http://xml.org/sax/features/namespaces".equals(name)) {
+            return namespaces;
+        } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
+            return namespacePrefixes;
+        } else {
+            throw new SAXNotRecognizedException("Feature '" + name
+                    + "' not recognized or supported by Document2SAXAdapter");
+        }
+
+    }
+
+
+
+    /**
+     * Set the state of a feature.
+     *
+     * <p>The feature name is any fully-qualified URI.  It is
+     * possible for an XMLReader to recognize a feature name but
+     * to be unable to set its value; this is especially true
+     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser Parser},
+     * which has no way of affecting whether the underlying parser is
+     * validating, for example.</p>
+     *
+     * <p>All XMLReaders are required to support setting
+     * http://xml.org/sax/features/namespaces to true and
+     * http://xml.org/sax/features/namespace-prefixes to false.</p>
+     *
+     * <p>Some feature values may be immutable or mutable only
+     * in specific contexts, such as before, during, or after
+     * a parse.</p>
+     *
+     * @param name The feature name, which is a fully-qualified URI.
+     * @param value The requested state of the feature (true or false).
+     * @exception SAXNotRecognizedException When the
+     * XMLReader does not recognize the feature name.
+     * @exception SAXNotSupportedException When the
+     * XMLReader recognizes the feature name but
+     * cannot set the requested value.
+     * @see #getFeature
+     */
+    public void setFeature(String name, boolean value)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        if ("http://xml.org/sax/features/namespaces".equals(name)) {
+            namespaces = value;
+        } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
+            namespacePrefixes = value;
+        } else {
+            throw new SAXNotRecognizedException("Feature '" + name
+                    + "' not recognized or supported by Document2SAXAdapter");
+        }
+
+    }
+
+
+
+    /**
+     * Look up the value of a property.
+     *
+     * <p>The property name is any fully-qualified URI.  It is
+     * possible for an XMLReader to recognize a property name but
+     * to be unable to return its state; this is especially true
+     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
+     * Parser}.</p>
+     *
+     * <p>XMLReaders are not required to recognize any specific
+     * property names, though an initial core set is documented for
+     * SAX2.</p>
+     *
+     * <p>Some property values may be available only in specific
+     * contexts, such as before, during, or after a parse.</p>
+     *
+     * <p>Implementors are free (and encouraged) to invent their own properties,
+     * using names built on their own URIs.</p>
+     *
+     * @param name The property name, which is a fully-qualified URI.
+     * @return The current value of the property.
+     * @exception SAXNotRecognizedException When the
+     * XMLReader does not recognize the property name.
+     * @exception SAXNotSupportedException When the
+     * XMLReader recognizes the property name but
+     * cannot determine its value at this time.
+     * @see #setProperty
+     */
+    public Object getProperty(String name)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        throw new SAXNotRecognizedException("Property '" + name
+                + "' not recognized or supported by Document2SAXAdapter");
+    }
+
+
+
+    /**
+     * Set the value of a property.
+     *
+     * <p>The property name is any fully-qualified URI.  It is
+     * possible for an XMLReader to recognize a property name but
+     * to be unable to set its value; this is especially true
+     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
+     * Parser}.</p>
+     *
+     * <p>XMLReaders are not required to recognize setting
+     * any specific property names, though a core set is provided with
+     * SAX2.</p>
+     *
+     * <p>Some property values may be immutable or mutable only
+     * in specific contexts, such as before, during, or after
+     * a parse.</p>
+     *
+     * <p>This method is also the standard mechanism for setting
+     * extended handlers.</p>
+     *
+     * @param name The property name, which is a fully-qualified URI.
+     * @param value The requested value for the property.
+     * @exception SAXNotRecognizedException When the
+     * XMLReader does not recognize the property name.
+     * @exception SAXNotSupportedException When the
+     * XMLReader recognizes the property name but
+     * cannot set the requested value.
+     */
+    public void setProperty(String name, Object value)
+            throws SAXNotRecognizedException, SAXNotSupportedException {
+        throw new SAXNotRecognizedException("Property '" + name
+                + "' not recognized or supported by Document2SAXAdapter");
+    }
+
+
+
+    // //////////////////////////////////////////////////////////////////
+    // Event handlers.
+    // //////////////////////////////////////////////////////////////////
+    private EntityResolver entityResolver = null;
+    private DTDHandler dtdHandler = null;
+    private ContentHandler contentHandler = null;
+    private ErrorHandler errorHandler = null;
+
+
+    /**
+     * Allow an application to register an entity resolver.
+     *
+     * <p>If the application does not register an entity resolver,
+     * the XMLReader will perform its own default resolution.</p>
+     *
+     * <p>Applications may register a new or different resolver in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * resolver immediately.</p>
+     *
+     * @param resolver The entity resolver.
+     * @see #getEntityResolver
+     */
+    public void setEntityResolver(EntityResolver resolver) {
+        entityResolver = resolver;
+    }
+
+
+
+    /**
+     * Return the current entity resolver.
+     *
+     * @return The current entity resolver, or null if none
+     * has been registered.
+     * @see #setEntityResolver
+     */
+    public EntityResolver getEntityResolver() {
+        return entityResolver;
+    }
+
+
+
+    /**
+     * Allow an application to register a DTD event handler.
+     *
+     * <p>If the application does not register a DTD handler, all DTD
+     * events reported by the SAX parser will be silently ignored.</p>
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * handler immediately.</p>
+     *
+     * @param handler The DTD handler.
+     * @see #getDTDHandler
+     */
+    public void setDTDHandler(DTDHandler handler) {
+        dtdHandler = handler;
+    }
+
+
+
+    /**
+     * Return the current DTD handler.
+     *
+     * @return The current DTD handler, or null if none
+     * has been registered.
+     * @see #setDTDHandler
+     */
+    public DTDHandler getDTDHandler() {
+        return dtdHandler;
+    }
+
+
+
+    /**
+     * Allow an application to register a content event handler.
+     *
+     * <p>If the application does not register a content handler, all
+     * content events reported by the SAX parser will be silently
+     * ignored.</p>
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * handler immediately.</p>
+     *
+     * @param handler The content handler.
+     * @see #getContentHandler
+     */
+    public void setContentHandler(ContentHandler handler) {
+        contentHandler = handler;
+    }
+
+
+
+    /**
+     * Return the current content handler.
+     *
+     * @return The current content handler, or null if none
+     * has been registered.
+     * @see #setContentHandler
+     */
+    public ContentHandler getContentHandler() {
+        return contentHandler;
+    }
+
+
+
+    /**
+     * Allow an application to register an error event handler.
+     *
+     * <p>If the application does not register an error handler, all
+     * error events reported by the SAX parser will be silently
+     * ignored; however, normal processing may not continue.  It is
+     * highly recommended that all SAX applications implement an
+     * error handler to avoid unexpected bugs.</p>
+     *
+     * <p>Applications may register a new or different handler in the
+     * middle of a parse, and the SAX parser must begin using the new
+     * handler immediately.</p>
+     *
+     * @param handler The error handler.
+     * @see #getErrorHandler
+     */
+    public void setErrorHandler(ErrorHandler handler) {
+        errorHandler = handler;
+    }
+
+    /**
+     * Return the current error handler.
+     *
+     * @return The current error handler, or null if none
+     * has been registered.
+     * @see #setErrorHandler
+     */
+    public ErrorHandler getErrorHandler() {
+        return errorHandler;
+    }
+
+
+
+    // //////////////////////////////////////////////////////////////////
+    // Parsing.
+    // //////////////////////////////////////////////////////////////////
+
+    /**
+     * Parse an XML DOM document.
+     *
+     *
+     *
+     * @param input The input source for the top-level of the
+     * XML document.
+     * @exception SAXException Any SAX exception, possibly
+     * wrapping another exception.
+     * @exception IOException An IO exception from the parser,
+     * possibly from a byte stream or character stream
+     * supplied by the application.
+     * @see org.xml.sax.InputSource
+     * @see #parse(java.lang.String)
+     * @see #setEntityResolver
+     * @see #setDTDHandler
+     * @see #setContentHandler
+     * @see #setErrorHandler
+     */
+    public void parse(InputSource input) throws IOException, SAXException {
+        if (input instanceof DocumentInputSource) {
+            Document document = ((DocumentInputSource)input).getDocument();
+            if (contentHandler == null) {
+                throw new SAXException("ContentHandler is null. Please use setContentHandler()");
+            }
+
+            // refactored from org.apache.fop.apps.Driver
+            /* most of this code is modified from John Cowan's */
+
+            Node currentNode;
+            AttributesImpl currentAtts;
+
+            /* temporary array for making Strings into character arrays */
+            char[] array = null;
+
+            currentAtts = new AttributesImpl();
+
+            /* start at the document element */
+            currentNode = document;
+            while (currentNode != null) {
+                switch (currentNode.getNodeType()) {
+                case Node.DOCUMENT_NODE:
+                    contentHandler.startDocument();
+                    break;
+                case Node.CDATA_SECTION_NODE:
+                case Node.TEXT_NODE:
+                    String data = currentNode.getNodeValue();
+                    int datalen = data.length();
+                    if (array == null || array.length < datalen) {
+                        /*
+                         * if the array isn't big enough, make a new
+                         * one
+                         */
+                        array = new char[datalen];
+                    }
+                    data.getChars(0, datalen, array, 0);
+                    contentHandler.characters(array, 0, datalen);
+                    break;
+                case Node.PROCESSING_INSTRUCTION_NODE:
+                    contentHandler.processingInstruction(currentNode.getNodeName(),
+                                                          currentNode.getNodeValue());
+                    break;
+                case Node.ELEMENT_NODE:
+                    NamedNodeMap map = currentNode.getAttributes();
+                    currentAtts.clear();
+                    for (int i = map.getLength() - 1; i >= 0; i--) {
+                        Attr att = (Attr)map.item(i);
+                        currentAtts.addAttribute(att.getNamespaceURI(),
+                                                 att.getLocalName(),
+                                                 att.getName(), "CDATA",
+                                                 att.getValue());
+                    }
+                    contentHandler.startElement(currentNode.getNamespaceURI(),
+                                                 currentNode.getLocalName(),
+                                                 currentNode.getNodeName(),
+                                                 currentAtts);
+                    break;
+                }
+
+                Node nextNode = currentNode.getFirstChild();
+                if (nextNode != null) {
+                    currentNode = nextNode;
+                    continue;
+                }
+
+                while (currentNode != null) {
+                    switch (currentNode.getNodeType()) {
+                    case Node.DOCUMENT_NODE:
+                        contentHandler.endDocument();
+                        break;
+                    case Node.ELEMENT_NODE:
+                        contentHandler.endElement(currentNode.getNamespaceURI(),
+                                                   currentNode.getLocalName(),
+                                                   currentNode.getNodeName());
+                        break;
+                    }
+
+                    nextNode = currentNode.getNextSibling();
+                    if (nextNode != null) {
+                        currentNode = nextNode;
+                        break;
+                    }
+
+                    currentNode = currentNode.getParentNode();
+                }
+            }
+
+        } else {
+            throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource");
+        }
+
+    }
+
+
+
+    /**
+     * DocumentReader requires a DocumentInputSource, so this is not
+     * implements and simply throws a SAXException. Use parse(DocumentInputSource)
+     * instead
+     *
+     * @param systemId The system identifier (URI).
+     * @exception SAXException Any SAX exception, possibly
+     * wrapping another exception.
+     * @exception IOException An IO exception from the parser,
+     * possibly from a byte stream or character stream
+     * supplied by the application.
+     * @see #parse(org.xml.sax.InputSource)
+     */
+    public void parse(String systemId) throws IOException, SAXException {
+        throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource");
+    }
+
+}
+
+
index ed4f3b50e57d4c09a965986d984967dde22aa751..e5ffada6e4094d55e34d10f7625b783961fc898b 100644 (file)
@@ -38,8 +38,6 @@ import org.apache.fop.fo.FOTreeHandler;
 import org.apache.fop.render.awt.AWTRenderer;
 import org.apache.fop.render.mif.MIFHandler;
 import org.apache.fop.render.rtf.RTFHandler;
-import org.apache.fop.tools.DocumentInputSource;
-import org.apache.fop.tools.DocumentReader;
 
 /**
  * Primary class that drives overall FOP process.
@@ -163,6 +161,9 @@ public class Driver implements Constants {
             throw new IllegalStateException("Driver already initialized");
         }
         treeBuilder = new FOTreeBuilder();
+        if (foUserAgent == null) {
+            foUserAgent = new FOUserAgent();
+        }
     }
 
     /**
index 6d8b7966d6d9c54bef6d32525bcc89e9cf97ab7a..d4aa1f1f53b50fd63f84436424aaade407240cca 100644 (file)
@@ -73,7 +73,7 @@ public class Flow extends FObj {
      * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
      * XSL/FOP Content Model: marker* (%block;)+
      */
-     protected void validateChildNode(Locator loc, String nsURI, String localName) {
+    protected void validateChildNode(Locator loc, String nsURI, String localName) {
         if (nsURI == FOElementMapping.URI && localName.equals("marker")) {
             if (blockItemFound) {
                nodesOutOfOrderError(loc, "fo:marker", "(%block;)");
index 6fe6a67f165989dc58d5da55dd7642fc92427488..f33e70371451018bb87893303c407a11c8038df4 100644 (file)
 
 package org.apache.fop.fo.pagination;
 
+// XML
+import org.xml.sax.Attributes;
+import org.xml.sax.Locator;
+
 // FOP
+import org.apache.fop.apps.FOPException;
+import org.apache.fop.fo.FOElementMapping;
 import org.apache.fop.fo.FONode;
 import org.apache.fop.fo.FOTreeVisitor;
-import org.apache.fop.apps.FOPException;
 
 /**
  * Class modelling the fo:static-content object. See Sec. 6.4.19 of the XSL-FO
@@ -39,6 +44,27 @@ public class StaticContent extends Flow {
     private void setup() {
     }
 
+    /**
+     * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
+     * XSL/FOP Content Model: (%block;)+
+     */
+    protected void validateChildNode(Locator loc, String nsURI, String localName) {
+        if (!isBlockItem(nsURI, localName)) {
+            invalidChildError(loc, nsURI, localName);
+        }
+    }
+
+    /**
+     * Make sure content model satisfied, if so then tell the
+     * StructureRenderer that we are at the end of the flow.
+     * @see org.apache.fop.fo.FONode#end
+     */
+    protected void end() {
+        if (children == null) {
+            missingChildElementError("(%block;)+");
+        }
+    }
+
     /**
      * flowname checking is more stringient for static content currently
      * @param name the flow-name to set
diff --git a/src/java/org/apache/fop/tools/DocumentInputSource.java b/src/java/org/apache/fop/tools/DocumentInputSource.java
deleted file mode 100644 (file)
index 92fc6ed..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-package org.apache.fop.tools;
-
-import org.w3c.dom.Document;
-import org.xml.sax.InputSource;
-
-/**
- * This is an InputSource to be used with DocumentReader.
- *
- * @author Kelly A Campbell
- */
-public class DocumentInputSource extends InputSource {
-    
-    private Document document;
-
-    /**
-     * Default constructor.
-     */
-    public DocumentInputSource() {
-        super();
-    }
-
-    /**
-     * Main constructor
-     * @param document the DOM document to use as input
-     */
-    public DocumentInputSource(Document document) {
-        this();
-        setDocument(document);
-    }
-
-    /**
-     * Returns the input document.
-     * @return the input DOM document.
-     */
-    public Document getDocument() {
-        return this.document;
-    }
-
-    /**
-     * Sets the input document.
-     * @param document the DOM document to use as input
-     */
-    public void setDocument(Document document) {
-        this.document = document;
-    }
-
-}
-
-
diff --git a/src/java/org/apache/fop/tools/DocumentReader.java b/src/java/org/apache/fop/tools/DocumentReader.java
deleted file mode 100644 (file)
index db2fe6c..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- * Copyright 1999-2004 The Apache Software Foundation.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
- *      http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* $Id$ */
-package org.apache.fop.tools;
-
-import java.io.IOException;
-
-// DOM
-import org.w3c.dom.Attr;
-import org.w3c.dom.Document;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-
-// SAX
-import org.xml.sax.ContentHandler;
-import org.xml.sax.DTDHandler;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.ErrorHandler;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.SAXNotRecognizedException;
-import org.xml.sax.SAXNotSupportedException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.AttributesImpl;
-
-/**
- * This presents a DOM as an XMLReader to make it easy to use a Document
- * with a SAX-based implementation.
- *
- * @author Kelly A Campbell
- *
- */
-
-public class DocumentReader implements XMLReader {
-
-    // //////////////////////////////////////////////////////////////////
-    // Configuration.
-    // //////////////////////////////////////////////////////////////////
-    private boolean namespaces = true;
-    private boolean namespacePrefixes = true;
-
-
-    /**
-     * Look up the value of a feature.
-     *
-     * <p>The feature name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a feature name but
-     * to be unable to return its value; this is especially true
-     * in the case of an adapter for a SAX1 Parser, which has
-     * no way of knowing whether the underlying parser is
-     * performing validation or expanding external entities.</p>
-     *
-     * <p>All XMLReaders are required to recognize the
-     * http://xml.org/sax/features/namespaces and the
-     * http://xml.org/sax/features/namespace-prefixes feature names.</p>
-     *
-     * <p>Some feature values may be available only in specific
-     * contexts, such as before, during, or after a parse.</p>
-     *
-     * <p>Typical usage is something like this:</p>
-     *
-     * <pre>
-     * XMLReader r = new MySAXDriver();
-     *
-     * // try to activate validation
-     * try {
-     * r.setFeature("http://xml.org/sax/features/validation", true);
-     * } catch (SAXException e) {
-     * System.err.println("Cannot activate validation.");
-     * }
-     *
-     * // register event handlers
-     * r.setContentHandler(new MyContentHandler());
-     * r.setErrorHandler(new MyErrorHandler());
-     *
-     * // parse the first document
-     * try {
-     * r.parse("http://www.foo.com/mydoc.xml");
-     * } catch (IOException e) {
-     * System.err.println("I/O exception reading XML document");
-     * } catch (SAXException e) {
-     * System.err.println("XML exception reading document.");
-     * }
-     * </pre>
-     *
-     * <p>Implementors are free (and encouraged) to invent their own features,
-     * using names built on their own URIs.</p>
-     *
-     * @param name The feature name, which is a fully-qualified URI.
-     * @return The current state of the feature (true or false).
-     * @exception SAXNotRecognizedException When the
-     * XMLReader does not recognize the feature name.
-     * @exception SAXNotSupportedException When the
-     * XMLReader recognizes the feature name but
-     * cannot determine its value at this time.
-     * @see #setFeature
-     */
-    public boolean getFeature(String name)
-            throws SAXNotRecognizedException, SAXNotSupportedException {
-        if ("http://xml.org/sax/features/namespaces".equals(name)) {
-            return namespaces;
-        } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
-            return namespacePrefixes;
-        } else {
-            throw new SAXNotRecognizedException("Feature '" + name
-                    + "' not recognized or supported by Document2SAXAdapter");
-        }
-
-    }
-
-
-
-    /**
-     * Set the state of a feature.
-     *
-     * <p>The feature name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a feature name but
-     * to be unable to set its value; this is especially true
-     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser Parser},
-     * which has no way of affecting whether the underlying parser is
-     * validating, for example.</p>
-     *
-     * <p>All XMLReaders are required to support setting
-     * http://xml.org/sax/features/namespaces to true and
-     * http://xml.org/sax/features/namespace-prefixes to false.</p>
-     *
-     * <p>Some feature values may be immutable or mutable only
-     * in specific contexts, such as before, during, or after
-     * a parse.</p>
-     *
-     * @param name The feature name, which is a fully-qualified URI.
-     * @param value The requested state of the feature (true or false).
-     * @exception SAXNotRecognizedException When the
-     * XMLReader does not recognize the feature name.
-     * @exception SAXNotSupportedException When the
-     * XMLReader recognizes the feature name but
-     * cannot set the requested value.
-     * @see #getFeature
-     */
-    public void setFeature(String name, boolean value)
-            throws SAXNotRecognizedException, SAXNotSupportedException {
-        if ("http://xml.org/sax/features/namespaces".equals(name)) {
-            namespaces = value;
-        } else if ("http://xml.org/sax/features/namespace-prefixes".equals(name)) {
-            namespacePrefixes = value;
-        } else {
-            throw new SAXNotRecognizedException("Feature '" + name
-                    + "' not recognized or supported by Document2SAXAdapter");
-        }
-
-    }
-
-
-
-    /**
-     * Look up the value of a property.
-     *
-     * <p>The property name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a property name but
-     * to be unable to return its state; this is especially true
-     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
-     * Parser}.</p>
-     *
-     * <p>XMLReaders are not required to recognize any specific
-     * property names, though an initial core set is documented for
-     * SAX2.</p>
-     *
-     * <p>Some property values may be available only in specific
-     * contexts, such as before, during, or after a parse.</p>
-     *
-     * <p>Implementors are free (and encouraged) to invent their own properties,
-     * using names built on their own URIs.</p>
-     *
-     * @param name The property name, which is a fully-qualified URI.
-     * @return The current value of the property.
-     * @exception SAXNotRecognizedException When the
-     * XMLReader does not recognize the property name.
-     * @exception SAXNotSupportedException When the
-     * XMLReader recognizes the property name but
-     * cannot determine its value at this time.
-     * @see #setProperty
-     */
-    public Object getProperty(String name)
-            throws SAXNotRecognizedException, SAXNotSupportedException {
-        throw new SAXNotRecognizedException("Property '" + name
-                + "' not recognized or supported by Document2SAXAdapter");
-    }
-
-
-
-    /**
-     * Set the value of a property.
-     *
-     * <p>The property name is any fully-qualified URI.  It is
-     * possible for an XMLReader to recognize a property name but
-     * to be unable to set its value; this is especially true
-     * in the case of an adapter for a SAX1 {@link org.xml.sax.Parser
-     * Parser}.</p>
-     *
-     * <p>XMLReaders are not required to recognize setting
-     * any specific property names, though a core set is provided with
-     * SAX2.</p>
-     *
-     * <p>Some property values may be immutable or mutable only
-     * in specific contexts, such as before, during, or after
-     * a parse.</p>
-     *
-     * <p>This method is also the standard mechanism for setting
-     * extended handlers.</p>
-     *
-     * @param name The property name, which is a fully-qualified URI.
-     * @param value The requested value for the property.
-     * @exception SAXNotRecognizedException When the
-     * XMLReader does not recognize the property name.
-     * @exception SAXNotSupportedException When the
-     * XMLReader recognizes the property name but
-     * cannot set the requested value.
-     */
-    public void setProperty(String name, Object value)
-            throws SAXNotRecognizedException, SAXNotSupportedException {
-        throw new SAXNotRecognizedException("Property '" + name
-                + "' not recognized or supported by Document2SAXAdapter");
-    }
-
-
-
-    // //////////////////////////////////////////////////////////////////
-    // Event handlers.
-    // //////////////////////////////////////////////////////////////////
-    private EntityResolver entityResolver = null;
-    private DTDHandler dtdHandler = null;
-    private ContentHandler contentHandler = null;
-    private ErrorHandler errorHandler = null;
-
-
-    /**
-     * Allow an application to register an entity resolver.
-     *
-     * <p>If the application does not register an entity resolver,
-     * the XMLReader will perform its own default resolution.</p>
-     *
-     * <p>Applications may register a new or different resolver in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * resolver immediately.</p>
-     *
-     * @param resolver The entity resolver.
-     * @see #getEntityResolver
-     */
-    public void setEntityResolver(EntityResolver resolver) {
-        entityResolver = resolver;
-    }
-
-
-
-    /**
-     * Return the current entity resolver.
-     *
-     * @return The current entity resolver, or null if none
-     * has been registered.
-     * @see #setEntityResolver
-     */
-    public EntityResolver getEntityResolver() {
-        return entityResolver;
-    }
-
-
-
-    /**
-     * Allow an application to register a DTD event handler.
-     *
-     * <p>If the application does not register a DTD handler, all DTD
-     * events reported by the SAX parser will be silently ignored.</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The DTD handler.
-     * @see #getDTDHandler
-     */
-    public void setDTDHandler(DTDHandler handler) {
-        dtdHandler = handler;
-    }
-
-
-
-    /**
-     * Return the current DTD handler.
-     *
-     * @return The current DTD handler, or null if none
-     * has been registered.
-     * @see #setDTDHandler
-     */
-    public DTDHandler getDTDHandler() {
-        return dtdHandler;
-    }
-
-
-
-    /**
-     * Allow an application to register a content event handler.
-     *
-     * <p>If the application does not register a content handler, all
-     * content events reported by the SAX parser will be silently
-     * ignored.</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The content handler.
-     * @see #getContentHandler
-     */
-    public void setContentHandler(ContentHandler handler) {
-        contentHandler = handler;
-    }
-
-
-
-    /**
-     * Return the current content handler.
-     *
-     * @return The current content handler, or null if none
-     * has been registered.
-     * @see #setContentHandler
-     */
-    public ContentHandler getContentHandler() {
-        return contentHandler;
-    }
-
-
-
-    /**
-     * Allow an application to register an error event handler.
-     *
-     * <p>If the application does not register an error handler, all
-     * error events reported by the SAX parser will be silently
-     * ignored; however, normal processing may not continue.  It is
-     * highly recommended that all SAX applications implement an
-     * error handler to avoid unexpected bugs.</p>
-     *
-     * <p>Applications may register a new or different handler in the
-     * middle of a parse, and the SAX parser must begin using the new
-     * handler immediately.</p>
-     *
-     * @param handler The error handler.
-     * @see #getErrorHandler
-     */
-    public void setErrorHandler(ErrorHandler handler) {
-        errorHandler = handler;
-    }
-
-    /**
-     * Return the current error handler.
-     *
-     * @return The current error handler, or null if none
-     * has been registered.
-     * @see #setErrorHandler
-     */
-    public ErrorHandler getErrorHandler() {
-        return errorHandler;
-    }
-
-
-
-    // //////////////////////////////////////////////////////////////////
-    // Parsing.
-    // //////////////////////////////////////////////////////////////////
-
-    /**
-     * Parse an XML DOM document.
-     *
-     *
-     *
-     * @param input The input source for the top-level of the
-     * XML document.
-     * @exception SAXException Any SAX exception, possibly
-     * wrapping another exception.
-     * @exception IOException An IO exception from the parser,
-     * possibly from a byte stream or character stream
-     * supplied by the application.
-     * @see org.xml.sax.InputSource
-     * @see #parse(java.lang.String)
-     * @see #setEntityResolver
-     * @see #setDTDHandler
-     * @see #setContentHandler
-     * @see #setErrorHandler
-     */
-    public void parse(InputSource input) throws IOException, SAXException {
-        if (input instanceof DocumentInputSource) {
-            Document document = ((DocumentInputSource)input).getDocument();
-            if (contentHandler == null) {
-                throw new SAXException("ContentHandler is null. Please use setContentHandler()");
-            }
-
-            // refactored from org.apache.fop.apps.Driver
-            /* most of this code is modified from John Cowan's */
-
-            Node currentNode;
-            AttributesImpl currentAtts;
-
-            /* temporary array for making Strings into character arrays */
-            char[] array = null;
-
-            currentAtts = new AttributesImpl();
-
-            /* start at the document element */
-            currentNode = document;
-            while (currentNode != null) {
-                switch (currentNode.getNodeType()) {
-                case Node.DOCUMENT_NODE:
-                    contentHandler.startDocument();
-                    break;
-                case Node.CDATA_SECTION_NODE:
-                case Node.TEXT_NODE:
-                    String data = currentNode.getNodeValue();
-                    int datalen = data.length();
-                    if (array == null || array.length < datalen) {
-                        /*
-                         * if the array isn't big enough, make a new
-                         * one
-                         */
-                        array = new char[datalen];
-                    }
-                    data.getChars(0, datalen, array, 0);
-                    contentHandler.characters(array, 0, datalen);
-                    break;
-                case Node.PROCESSING_INSTRUCTION_NODE:
-                    contentHandler.processingInstruction(currentNode.getNodeName(),
-                                                          currentNode.getNodeValue());
-                    break;
-                case Node.ELEMENT_NODE:
-                    NamedNodeMap map = currentNode.getAttributes();
-                    currentAtts.clear();
-                    for (int i = map.getLength() - 1; i >= 0; i--) {
-                        Attr att = (Attr)map.item(i);
-                        currentAtts.addAttribute(att.getNamespaceURI(),
-                                                 att.getLocalName(),
-                                                 att.getName(), "CDATA",
-                                                 att.getValue());
-                    }
-                    contentHandler.startElement(currentNode.getNamespaceURI(),
-                                                 currentNode.getLocalName(),
-                                                 currentNode.getNodeName(),
-                                                 currentAtts);
-                    break;
-                }
-
-                Node nextNode = currentNode.getFirstChild();
-                if (nextNode != null) {
-                    currentNode = nextNode;
-                    continue;
-                }
-
-                while (currentNode != null) {
-                    switch (currentNode.getNodeType()) {
-                    case Node.DOCUMENT_NODE:
-                        contentHandler.endDocument();
-                        break;
-                    case Node.ELEMENT_NODE:
-                        contentHandler.endElement(currentNode.getNamespaceURI(),
-                                                   currentNode.getLocalName(),
-                                                   currentNode.getNodeName());
-                        break;
-                    }
-
-                    nextNode = currentNode.getNextSibling();
-                    if (nextNode != null) {
-                        currentNode = nextNode;
-                        break;
-                    }
-
-                    currentNode = currentNode.getParentNode();
-                }
-            }
-
-        } else {
-            throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource");
-        }
-
-    }
-
-
-
-    /**
-     * DocumentReader requires a DocumentInputSource, so this is not
-     * implements and simply throws a SAXException. Use parse(DocumentInputSource)
-     * instead
-     *
-     * @param systemId The system identifier (URI).
-     * @exception SAXException Any SAX exception, possibly
-     * wrapping another exception.
-     * @exception IOException An IO exception from the parser,
-     * possibly from a byte stream or character stream
-     * supplied by the application.
-     * @see #parse(org.xml.sax.InputSource)
-     */
-    public void parse(String systemId) throws IOException, SAXException {
-        throw new SAXException("DocumentReader only supports parsing of a DocumentInputSource");
-    }
-
-}
-
-