aboutsummaryrefslogtreecommitdiffstats
path: root/src/java
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2009-09-22 11:49:06 +0000
committerVincent Hennebert <vhennebert@apache.org>2009-09-22 11:49:06 +0000
commitdbaf63a64da3aaa4ecc1dc6de510cca85617a51a (patch)
tree178577f0e28833e2d4469f92b073ee2633227c01 /src/java
parent0e5a789b6b0604bb9c6cc9b782c22f490917e9f9 (diff)
downloadxmlgraphics-fop-dbaf63a64da3aaa4ecc1dc6de510cca85617a51a.tar.gz
xmlgraphics-fop-dbaf63a64da3aaa4ecc1dc6de510cca85617a51a.zip
Factorized into a new class the parsing of the reduced FO tree, that was duplicated in IFSerializer and PDFDocumentHandler.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_Accessibility@817617 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java')
-rw-r--r--src/java/org/apache/fop/accessibility/StructureTree.java98
-rw-r--r--src/java/org/apache/fop/accessibility/TransformerNodeEndProcessing.java9
-rw-r--r--src/java/org/apache/fop/apps/FOUserAgent.java26
-rw-r--r--src/java/org/apache/fop/render/intermediate/IFSerializer.java73
-rw-r--r--src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java149
5 files changed, 157 insertions, 198 deletions
diff --git a/src/java/org/apache/fop/accessibility/StructureTree.java b/src/java/org/apache/fop/accessibility/StructureTree.java
new file mode 100644
index 000000000..0be785eb2
--- /dev/null
+++ b/src/java/org/apache/fop/accessibility/StructureTree.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.accessibility;
+
+import java.util.Iterator;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A reduced version of the document's FO tree, containing only its logical
+ * structure. Used by accessible output formats.
+ */
+public final class StructureTree {
+
+ private final Node reducedFOTree;
+
+ private static class NamespaceContextImpl implements NamespaceContext {
+
+ private String uri;
+ private String prefix;
+
+ public NamespaceContextImpl() {
+ }
+
+ public NamespaceContextImpl(String prefix, String uri) {
+ this.uri = uri;
+ this.prefix = prefix;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return uri;
+ }
+
+ public void setNamespaceURI(String uri) {
+ this.uri = uri;
+ }
+
+ public String getPrefix(String uri) {
+ return prefix;
+ }
+
+ public void setPrefix(String prefix) {
+ this.prefix = prefix;
+ }
+
+ public Iterator getPrefixes(String uri) {
+ return null;
+ }
+ }
+
+ StructureTree(Node reducedFOTree) {
+ this.reducedFOTree = reducedFOTree;
+ }
+
+ /**
+ * Returns the list of nodes that are the children of the given page sequence.
+ *
+ * @param number number of the page sequence, 1-based
+ * @return its children nodes
+ */
+ public NodeList getPageSequence(int number) {
+ XPath xpath = XPathFactory.newInstance().newXPath();
+ NamespaceContext namespaceContext = new NamespaceContextImpl("fo",
+ "http://www.w3.org/1999/XSL/Format");
+ xpath.setNamespaceContext(namespaceContext);
+ String xpathExpr = "/fo:root/fo:page-sequence[" + Integer.toString(number) + "]/*";
+
+ try {
+ return (NodeList) xpath.evaluate(xpathExpr, reducedFOTree, XPathConstants.NODESET);
+ } catch (XPathExpressionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/src/java/org/apache/fop/accessibility/TransformerNodeEndProcessing.java b/src/java/org/apache/fop/accessibility/TransformerNodeEndProcessing.java
index 34974233a..c89f72623 100644
--- a/src/java/org/apache/fop/accessibility/TransformerNodeEndProcessing.java
+++ b/src/java/org/apache/fop/accessibility/TransformerNodeEndProcessing.java
@@ -28,14 +28,14 @@ import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
+import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
+import org.apache.commons.io.output.ByteArrayOutputStream;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
-import org.apache.commons.io.output.ByteArrayOutputStream;
-
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
@@ -76,10 +76,9 @@ class TransformerNodeEndProcessing extends TransformerNode {
byte[] enrichedFO = enrichedFOBuffer.toByteArray();
Transformer transformer = AccessibilityUtil.getReduceFOTreeTemplates().newTransformer();
Source src = new StreamSource(new ByteArrayInputStream(enrichedFO));
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- Result res = new StreamResult(out);
+ DOMResult res = new DOMResult();
transformer.transform(src, res);
- userAgent.setReducedFOTree(out.toByteArray());
+ userAgent.setStructureTree(new StructureTree(res.getNode()));
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
saxParserFactory.setNamespaceAware(true);
diff --git a/src/java/org/apache/fop/apps/FOUserAgent.java b/src/java/org/apache/fop/apps/FOUserAgent.java
index 13db8d5ef..0ed5151e0 100644
--- a/src/java/org/apache/fop/apps/FOUserAgent.java
+++ b/src/java/org/apache/fop/apps/FOUserAgent.java
@@ -38,6 +38,7 @@ import org.apache.xmlgraphics.image.loader.impl.AbstractImageSessionContext;
import org.apache.fop.Version;
import org.apache.fop.accessibility.AccessibilityUtil;
+import org.apache.fop.accessibility.StructureTree;
import org.apache.fop.events.DefaultEventBroadcaster;
import org.apache.fop.events.Event;
import org.apache.fop.events.EventBroadcaster;
@@ -100,8 +101,7 @@ public class FOUserAgent {
private boolean conserveMemoryPolicy = false;
private EventBroadcaster eventBroadcaster = new FOPEventBroadcaster();
- //TODO Verify that a byte array is the best solution here
- private byte[] reducedFOTree; // accessibility: reduced FO
+ private StructureTree structureTree;
/** Producer: Metadata element for the system/software that produces
* the document. (Some renderers can store this in the document.)
@@ -664,20 +664,24 @@ public class FOUserAgent {
}
/**
- * Used for accessibility. Stores the reduced FO tree (the result from the second transform)
- * for later use.
- * @param reducedFOTree the result from 2nd transform
+ * Sets the document's structure tree, for use by accessible output formats.
+ *
+ * @param structureTree a simplified version of the FO tree, retaining only
+ * its logical structure
*/
- public void setReducedFOTree(byte[] reducedFOTree) {
- this.reducedFOTree = reducedFOTree;
+ public void setStructureTree(StructureTree structureTree) {
+ this.structureTree = structureTree;
}
/**
- * Used for accessibility. Returns the reduced FO tree.
- * @return result from 2nd transform as byte array
+ * Returns the document's structure tree, for use by accessible output
+ * formats.
+ *
+ * @return a simplified version of the FO tree, retaining only its logical
+ * structure
*/
- public byte[] getReducedFOTree() {
- return this.reducedFOTree;
+ public StructureTree getStructureTree() {
+ return this.structureTree;
}
}
diff --git a/src/java/org/apache/fop/render/intermediate/IFSerializer.java b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
index 2d009d58d..281301fbe 100644
--- a/src/java/org/apache/fop/render/intermediate/IFSerializer.java
+++ b/src/java/org/apache/fop/render/intermediate/IFSerializer.java
@@ -25,33 +25,22 @@ import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Stack;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.apache.xmlgraphics.util.QName;
import org.apache.xmlgraphics.util.XMLizable;
+import org.apache.fop.accessibility.StructureTree;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.render.PrintRendererConfigurator;
import org.apache.fop.render.RenderingContext;
@@ -76,45 +65,10 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
private IFDocumentHandler mimicHandler;
private int pageSequenceCounter; // used for accessibility
- private DocumentBuilder parser = null; // used for accessibility
- private Document doc = null; // used for accessibility
/** Holds the intermediate format state */
private IFState state;
- private static class NamespaceContextImpl implements NamespaceContext {
-
- public String uri;
- public String prefix;
-
- public NamespaceContextImpl() {
- }
-
- public NamespaceContextImpl(String prefix, String uri) {
- this.uri = uri;
- this.prefix = prefix;
- }
-
- public String getNamespaceURI(String prefix) {
- return uri;
- }
- public void setNamespaceURI(String uri) {
- this.uri = uri;
- }
-
- public String getPrefix(String uri) {
- return prefix;
- }
-
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
- public Iterator getPrefixes(String uri) {
- return null;
- }
-
- }
-
/**
* Default constructor.
*/
@@ -202,16 +156,8 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
handler.startPrefixMapping(DocumentNavigationExtensionConstants.PREFIX,
DocumentNavigationExtensionConstants.NAMESPACE);
handler.startElement(EL_DOCUMENT);
- if (this.getUserAgent().isAccessibilityEnabled()) {
- pageSequenceCounter = 0;
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- parser = factory.newDocumentBuilder();
- }
} catch (SAXException e) {
throw new IFException("SAX error in startDocument()", e);
- } catch (ParserConfigurationException pce) {
- throw new IFException("Error creating new DocumentBuilder", pce);
}
}
@@ -273,18 +219,9 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
addForeignAttributes(atts);
handler.startElement(EL_PAGE_SEQUENCE, atts);
if (this.getUserAgent().isAccessibilityEnabled()) {
- if (doc == null) {
- doc = parser.parse(
- new ByteArrayInputStream(this.getUserAgent().getReducedFOTree()));
- }
+ StructureTree structureTree = getUserAgent().getStructureTree();
handler.startElement(EL_STRUCTURE_TREE); // add structure tree
- String xpathExpr
- = "/fo:root/fo:page-sequence[" + Integer.toString(++pageSequenceCounter) + "]/*";
- XPath xpath = XPathFactory.newInstance().newXPath();
- NamespaceContext namespaceContext
- = new NamespaceContextImpl("fo", "http://www.w3.org/1999/XSL/Format");
- xpath.setNamespaceContext(namespaceContext);
- NodeList nodes = (NodeList)xpath.evaluate(xpathExpr, doc, XPathConstants.NODESET);
+ NodeList nodes = structureTree.getPageSequence(++pageSequenceCounter);
for (int i = 0, n = nodes.getLength(); i < n; i++) {
Node node = nodes.item(i);
new DOM2SAX(handler).writeFragment(node);
@@ -293,10 +230,6 @@ public class IFSerializer extends AbstractXMLWritingIFDocumentHandler
}
} catch (SAXException e) {
throw new IFException("SAX error in startPageSequence()", e);
- } catch (XPathExpressionException e) {
- throw new IFException("Error while evaluating XPath expression", e);
- } catch (IOException ioe) {
- throw new IFException("I/O error while parsing structure tree", ioe);
}
}
diff --git a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
index 9e2b2cdb3..064682a3c 100644
--- a/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
+++ b/src/java/org/apache/fop/render/pdf/PDFDocumentHandler.java
@@ -25,31 +25,19 @@ import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.Rectangle2D.Double;
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import org.xml.sax.SAXException;
import org.apache.xmlgraphics.xmp.Metadata;
+import org.apache.fop.accessibility.StructureTree;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.fo.extensions.xmp.XMPMetadata;
import org.apache.fop.pdf.PDFAnnotList;
@@ -86,8 +74,6 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
/** the following variables are used for accessibility */
private int pageSequenceCounter;
- private DocumentBuilder parser = null;
- private Document reducedFOTree = null;
private Map structElemType = new HashMap();
private boolean accessEnabled = false;
private int parentTreeKey = -1;
@@ -97,41 +83,6 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
private Map structTreeMap = new HashMap();
private List parentTreeList = new java.util.ArrayList();
- private static class NamespaceContextImpl implements NamespaceContext {
-
- private String uri;
- private String prefix;
-
- public NamespaceContextImpl() {
- }
-
- public NamespaceContextImpl(String prefix, String uri) {
- this.uri = uri;
- this.prefix = prefix;
- }
-
- public String getNamespaceURI(String prefix) {
- return uri;
- }
-
- public void setNamespaceURI(String uri) {
- this.uri = uri;
- }
-
- public String getPrefix(String uri) {
- return prefix;
- }
-
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
-
- public Iterator getPrefixes(String uri) {
- return null;
- }
-
- }
-
private static final class ParentTreeEntry {
private final int position;
private final PDFObject object;
@@ -233,14 +184,9 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
parentTree = new PDFParentTree();
pageSequenceCounter = 0;
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- factory.setNamespaceAware(true);
- parser = factory.newDocumentBuilder();
}
} catch (IOException e) {
throw new IFException("I/O error in startDocument()", e);
- } catch (ParserConfigurationException pce) {
- throw new IFException("Error creating new DocumentBuilder", pce);
}
}
@@ -271,8 +217,6 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
parentTree.setNums(nums);
getStructTreeRoot().addParentTree(parentTree);
pdfDoc.outputTrailer(this.outputStream);
- parser = null;
- reducedFOTree = null;
structElemType = null;
parentTree = null;
structTreeMap = null;
@@ -308,65 +252,46 @@ public class PDFDocumentHandler extends AbstractBinaryWritingIFDocumentHandler {
}
if (getUserAgent().isAccessibilityEnabled()) {
- try {
- if (this.pdfDoc.getRoot().getLanguage() == null) {
- String fallbackLanguage;
- if (this.pdfDoc.getProfile().getPDFAMode().isPDFA1LevelA()) {
- //According to Annex B of ISO-19005-1:2005(E), section B.2
- fallbackLanguage = "x-unknown";
- } else {
- //No language has been set on the first page-sequence, so fall back to "en".
- fallbackLanguage = "en";
- }
- this.pdfDoc.getRoot().setLanguage(fallbackLanguage);
+ if (this.pdfDoc.getRoot().getLanguage() == null) {
+ String fallbackLanguage;
+ if (this.pdfDoc.getProfile().getPDFAMode().isPDFA1LevelA()) {
+ //According to Annex B of ISO-19005-1:2005(E), section B.2
+ fallbackLanguage = "x-unknown";
+ } else {
+ //No language has been set on the first page-sequence, so fall back to "en".
+ fallbackLanguage = "en";
}
+ this.pdfDoc.getRoot().setLanguage(fallbackLanguage);
+ }
- if (reducedFOTree == null) {
- reducedFOTree = parser.parse(
- new ByteArrayInputStream(this.getUserAgent().getReducedFOTree()));
- }
- PDFStructElem parent = (PDFStructElem)getStructTreeRoot().getFirstChild();
- PDFStructElem structElemPart = new PDFStructElem(parent,
- FOToPDFRoleMap.mapFormattingObject("page-sequence", parent));
- if (getContext().getLanguage() != null) {
- structElemPart.setLanguage(getContext().getLanguage());
- }
- this.pdfDoc.assignObjectNumber(structElemPart);
- this.pdfDoc.addTrailerObject(structElemPart);
- parent.addKid(structElemPart);
-
- String xpathExpr = "/fo:root/fo:page-sequence["
- + Integer.toString(++pageSequenceCounter) + "]/*";
- XPath xpath = XPathFactory.newInstance().newXPath();
- NamespaceContext namespaceContext = new NamespaceContextImpl("fo",
- "http://www.w3.org/1999/XSL/Format");
- xpath.setNamespaceContext(namespaceContext);
-
- NodeList nodes = (NodeList) xpath.evaluate(xpathExpr, reducedFOTree,
- XPathConstants.NODESET);
-
- for (int i = 0, n = nodes.getLength(); i < n; i++) {
- Node node = nodes.item(i);
- if (node.getNodeName().equals("fo:flow")
- || node.getNodeName().equals("fo:static-content")) {
- PDFStructElem structElemSect = new PDFStructElem(structElemPart,
- FOToPDFRoleMap.mapFormattingObject(node.getLocalName(),
- structElemPart));
- this.pdfDoc.assignObjectNumber(structElemSect);
- this.pdfDoc.addTrailerObject(structElemSect);
- structElemPart.addKid(structElemSect);
- NodeList iNodes = node.getChildNodes();
- for (int j = 0, m = iNodes.getLength(); j < m; j++) {
- processContent(iNodes.item(j), structElemSect, 1);
- }
+ StructureTree structureTree = getUserAgent().getStructureTree();
+ PDFStructElem parent = (PDFStructElem)getStructTreeRoot().getFirstChild();
+ PDFStructElem structElemPart = new PDFStructElem(parent,
+ FOToPDFRoleMap.mapFormattingObject("page-sequence", parent));
+ if (getContext().getLanguage() != null) {
+ structElemPart.setLanguage(getContext().getLanguage());
+ }
+ this.pdfDoc.assignObjectNumber(structElemPart);
+ this.pdfDoc.addTrailerObject(structElemPart);
+ parent.addKid(structElemPart);
+
+ NodeList nodes = structureTree.getPageSequence(++pageSequenceCounter);
+
+ for (int i = 0, n = nodes.getLength(); i < n; i++) {
+ Node node = nodes.item(i);
+ if (node.getNodeName().equals("fo:flow")
+ || node.getNodeName().equals("fo:static-content")) {
+ PDFStructElem structElemSect = new PDFStructElem(structElemPart,
+ FOToPDFRoleMap.mapFormattingObject(node.getLocalName(),
+ structElemPart));
+ this.pdfDoc.assignObjectNumber(structElemSect);
+ this.pdfDoc.addTrailerObject(structElemSect);
+ structElemPart.addKid(structElemSect);
+ NodeList iNodes = node.getChildNodes();
+ for (int j = 0, m = iNodes.getLength(); j < m; j++) {
+ processContent(iNodes.item(j), structElemSect, 1);
}
}
- } catch (SAXException e) {
- throw new IFException("SAX error in startPageSequence()", e);
- } catch (XPathExpressionException e) {
- throw new IFException("Error while evaluating XPath expression", e);
- } catch (IOException ioe) {
- throw new IFException("I/O error while parsing structure tree", ioe);
}
}
}