aboutsummaryrefslogtreecommitdiffstats
path: root/src/java/org/apache/fop/accessibility
diff options
context:
space:
mode:
authorVincent Hennebert <vhennebert@apache.org>2013-04-08 11:51:52 +0000
committerVincent Hennebert <vhennebert@apache.org>2013-04-08 11:51:52 +0000
commitce39d4c2fb899be5d8d705fe72e0153fde21e592 (patch)
treec16721a9a7f5313aaadafb0529370d278067eaa4 /src/java/org/apache/fop/accessibility
parente3c9f13598dc3bbcbe1ea34920972910625567c0 (diff)
downloadxmlgraphics-fop-ce39d4c2fb899be5d8d705fe72e0153fde21e592.tar.gz
xmlgraphics-fop-ce39d4c2fb899be5d8d705fe72e0153fde21e592.zip
FOP #2234: NPE when rendering a document with markers and accessibility is enabled
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1465599 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src/java/org/apache/fop/accessibility')
-rw-r--r--src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java6
-rw-r--r--src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java10
-rw-r--r--src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java12
-rw-r--r--src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java76
-rw-r--r--src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java87
5 files changed, 170 insertions, 21 deletions
diff --git a/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java b/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java
index c63c721e5..be1177635 100644
--- a/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java
+++ b/src/java/org/apache/fop/accessibility/DummyStructureTreeEventHandler.java
@@ -42,7 +42,7 @@ public final class DummyStructureTreeEventHandler implements StructureTreeEventH
}
/** {@inheritDoc} */
- public StructureTreeElement startNode(String name, Attributes attributes) {
+ public StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent) {
return null;
}
@@ -51,12 +51,12 @@ public final class DummyStructureTreeEventHandler implements StructureTreeEventH
}
/** {@inheritDoc} */
- public StructureTreeElement startImageNode(String name, Attributes attributes) {
+ public StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent) {
return null;
}
/** {@inheritDoc} */
- public StructureTreeElement startReferencedNode(String name, Attributes attributes) {
+ public StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent) {
return null;
}
diff --git a/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java b/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java
index 7a375ef20..0b8073e57 100644
--- a/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java
+++ b/src/java/org/apache/fop/accessibility/StructureTree2SAXEventAdapter.java
@@ -87,7 +87,7 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa
}
/** {@inheritDoc} */
- public StructureTreeElement startNode(String name, Attributes attributes) {
+ public StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent) {
try {
if (name.equals("#PCDATA")) {
name = "marked-content";
@@ -115,13 +115,13 @@ public final class StructureTree2SAXEventAdapter implements StructureTreeEventHa
}
/** {@inheritDoc} */
- public StructureTreeElement startImageNode(String name, Attributes attributes) {
- return startNode(name, attributes);
+ public StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent) {
+ return startNode(name, attributes, null);
}
/** {@inheritDoc} */
- public StructureTreeElement startReferencedNode(String name, Attributes attributes) {
- return startNode(name, attributes);
+ public StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent) {
+ return startNode(name, attributes, null);
}
}
diff --git a/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java b/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java
index 46b724626..53c27130c 100644
--- a/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java
+++ b/src/java/org/apache/fop/accessibility/StructureTreeEventHandler.java
@@ -43,9 +43,11 @@ public interface StructureTreeEventHandler {
*
* @param name the name of the structure tree node
* @param attributes the node properties
+ * @param parent the parent of the node. May be null, in which case the parent node is
+ * the node corresponding to the previous call to this method
* @return the corresponding structure tree element
*/
- StructureTreeElement startNode(String name, Attributes attributes);
+ StructureTreeElement startNode(String name, Attributes attributes, StructureTreeElement parent);
/**
* Ends a structure tree node.
@@ -59,9 +61,11 @@ public interface StructureTreeEventHandler {
*
* @param name the name of the structure tree node
* @param attributes the node properties
+ * @param parent the parent of the node. May be null, in which case the parent node is
+ * the node corresponding to the previous call to this method
* @return the corresponding structure tree element
*/
- StructureTreeElement startImageNode(String name, Attributes attributes);
+ StructureTreeElement startImageNode(String name, Attributes attributes, StructureTreeElement parent);
/**
* Starts a node that can be referenced by other nodes. This is usually a
@@ -69,9 +73,11 @@ public interface StructureTreeEventHandler {
*
* @param name the name of the structure tree node
* @param attributes the node properties
+ * @param parent the parent of the node. May be null, in which case the parent node is
+ * the node corresponding to the previous call to this method
* @return the corresponding structure tree element
*/
- StructureTreeElement startReferencedNode(String name, Attributes attributes);
+ StructureTreeElement startReferencedNode(String name, Attributes attributes, StructureTreeElement parent);
/**
* Ends a page sequence structure tree node.
diff --git a/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java b/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
index aaf112cb5..4614a7005 100644
--- a/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
+++ b/src/java/org/apache/fop/accessibility/fo/FO2StructureTreeConverter.java
@@ -19,6 +19,8 @@
package org.apache.fop.accessibility.fo;
+import java.util.HashMap;
+import java.util.Map;
import java.util.Stack;
import org.xml.sax.SAXException;
@@ -29,6 +31,7 @@ import org.apache.fop.fo.DelegatingFOEventHandler;
import org.apache.fop.fo.FOEventHandler;
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.extensions.ExternalDocument;
+import org.apache.fop.fo.flow.AbstractRetrieveMarker;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.Block;
import org.apache.fop.fo.flow.BlockContainer;
@@ -46,6 +49,8 @@ import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.flow.PageNumber;
import org.apache.fop.fo.flow.PageNumberCitation;
import org.apache.fop.fo.flow.PageNumberCitationLast;
+import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.fo.flow.RetrieveTableMarker;
import org.apache.fop.fo.flow.Wrapper;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody;
@@ -70,14 +75,30 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
/** The top of the {@link converters} stack. */
private FOEventHandler converter;
- private final Stack<FOEventHandler> converters = new Stack<FOEventHandler>();
+ private Stack<FOEventHandler> converters = new Stack<FOEventHandler>();
- private final FOEventHandler structureTreeEventTrigger;
+ private final StructureTreeEventTrigger structureTreeEventTrigger;
/** The descendants of some elements like fo:leader must be ignored. */
private final FOEventHandler eventSwallower = new FOEventHandler() {
};
+ private final Map<AbstractRetrieveMarker, State> states = new HashMap<AbstractRetrieveMarker, State>();
+
+ private static final class State {
+
+ private final FOEventHandler converter;
+
+ private final Stack<FOEventHandler> converters;
+
+ @SuppressWarnings("unchecked")
+ State(FO2StructureTreeConverter o) {
+ this.converter = o.converter;
+ this.converters = (Stack<FOEventHandler>) o.converters.clone();
+ }
+
+ }
+
/**
* Creates a new instance.
*
@@ -459,6 +480,57 @@ public class FO2StructureTreeConverter extends DelegatingFOEventHandler {
}
@Override
+ public void startRetrieveMarker(RetrieveMarker retrieveMarker) {
+ converter.startRetrieveMarker(retrieveMarker);
+ saveState(retrieveMarker);
+ super.startRetrieveMarker(retrieveMarker);
+ }
+
+ private void saveState(AbstractRetrieveMarker retrieveMarker) {
+ states.put(retrieveMarker, new State(this));
+ }
+
+ @Override
+ public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
+ converter.endRetrieveMarker(retrieveMarker);
+ super.endRetrieveMarker(retrieveMarker);
+ }
+
+ @Override
+ public void restoreState(RetrieveMarker retrieveMarker) {
+ restoreRetrieveMarkerState(retrieveMarker);
+ converter.restoreState(retrieveMarker);
+ super.restoreState(retrieveMarker);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void restoreRetrieveMarkerState(AbstractRetrieveMarker retrieveMarker) {
+ State state = states.get(retrieveMarker);
+ this.converter = state.converter;
+ this.converters = (Stack<FOEventHandler>) state.converters.clone();
+ }
+
+ @Override
+ public void startRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+ converter.startRetrieveTableMarker(retrieveTableMarker);
+ saveState(retrieveTableMarker);
+ super.startRetrieveTableMarker(retrieveTableMarker);
+ }
+
+ @Override
+ public void endRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+ converter.endRetrieveTableMarker(retrieveTableMarker);
+ super.endRetrieveTableMarker(retrieveTableMarker);
+ }
+
+ @Override
+ public void restoreState(RetrieveTableMarker retrieveTableMarker) {
+ restoreRetrieveMarkerState(retrieveTableMarker);
+ converter.restoreState(retrieveTableMarker);
+ super.restoreState(retrieveTableMarker);
+ }
+
+ @Override
public void character(Character c) {
converter.character(c);
super.character(c);
diff --git a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
index 6a763a6f6..1a59bebfb 100644
--- a/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
+++ b/src/java/org/apache/fop/accessibility/fo/StructureTreeEventTrigger.java
@@ -19,7 +19,9 @@
package org.apache.fop.accessibility.fo;
+import java.util.HashMap;
import java.util.Locale;
+import java.util.Map;
import java.util.Stack;
import javax.xml.XMLConstants;
@@ -34,6 +36,7 @@ import org.apache.fop.fo.FOText;
import org.apache.fop.fo.extensions.ExtensionElementMapping;
import org.apache.fop.fo.extensions.InternalElementMapping;
import org.apache.fop.fo.flow.AbstractGraphics;
+import org.apache.fop.fo.flow.AbstractRetrieveMarker;
import org.apache.fop.fo.flow.BasicLink;
import org.apache.fop.fo.flow.Block;
import org.apache.fop.fo.flow.BlockContainer;
@@ -50,6 +53,8 @@ import org.apache.fop.fo.flow.ListItemLabel;
import org.apache.fop.fo.flow.PageNumber;
import org.apache.fop.fo.flow.PageNumberCitation;
import org.apache.fop.fo.flow.PageNumberCitationLast;
+import org.apache.fop.fo.flow.RetrieveMarker;
+import org.apache.fop.fo.flow.RetrieveTableMarker;
import org.apache.fop.fo.flow.Wrapper;
import org.apache.fop.fo.flow.table.Table;
import org.apache.fop.fo.flow.table.TableBody;
@@ -76,11 +81,30 @@ class StructureTreeEventTrigger extends FOEventHandler {
private LayoutMasterSet layoutMasterSet;
- private final Stack<Table> tables = new Stack<Table>();
+ private Stack<Table> tables = new Stack<Table>();
- private final Stack<Boolean> inTableHeader = new Stack<Boolean>();
+ private Stack<Boolean> inTableHeader = new Stack<Boolean>();
- private final Stack<Locale> locales = new Stack<Locale>();
+ private Stack<Locale> locales = new Stack<Locale>();
+
+ private final Map<AbstractRetrieveMarker, State> states = new HashMap<AbstractRetrieveMarker, State>();
+
+ private static final class State {
+
+ private final Stack<Table> tables;
+
+ private final Stack<Boolean> inTableHeader;
+
+ private final Stack<Locale> locales;
+
+ @SuppressWarnings("unchecked")
+ State(StructureTreeEventTrigger o) {
+ this.tables = (Stack<Table>) o.tables.clone();
+ this.inTableHeader = (Stack<Boolean>) o.inTableHeader.clone();
+ this.locales = (Stack<Locale>) o.locales.clone();
+ }
+
+ }
public StructureTreeEventTrigger(StructureTreeEventHandler structureTreeEventHandler) {
this.structureTreeEventHandler = structureTreeEventHandler;
@@ -415,6 +439,50 @@ class StructureTreeEventTrigger extends FOEventHandler {
}
@Override
+ public void startRetrieveMarker(RetrieveMarker retrieveMarker) {
+ startElementWithID(retrieveMarker);
+ saveState(retrieveMarker);
+ }
+
+ void saveState(AbstractRetrieveMarker retrieveMarker) {
+ states.put(retrieveMarker, new State(this));
+ }
+
+ @Override
+ public void endRetrieveMarker(RetrieveMarker retrieveMarker) {
+ endElement(retrieveMarker);
+ }
+
+ @Override
+ public void restoreState(RetrieveMarker retrieveMarker) {
+ restoreRetrieveMarkerState(retrieveMarker);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void restoreRetrieveMarkerState(AbstractRetrieveMarker retrieveMarker) {
+ State state = states.get(retrieveMarker);
+ tables = (Stack<Table>) state.tables.clone();
+ inTableHeader = (Stack<Boolean>) state.inTableHeader.clone();
+ locales = (Stack<Locale>) state.locales.clone();
+ }
+
+ @Override
+ public void startRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+ startElementWithID(retrieveTableMarker);
+ saveState(retrieveTableMarker);
+ }
+
+ @Override
+ public void endRetrieveTableMarker(RetrieveTableMarker retrieveTableMarker) {
+ endElement(retrieveTableMarker);
+ }
+
+ @Override
+ public void restoreState(RetrieveTableMarker retrieveTableMarker) {
+ restoreRetrieveMarkerState(retrieveTableMarker);
+ }
+
+ @Override
public void character(Character c) {
AttributesImpl attributes = createLangAttribute(c.getCommonHyphenation());
startElementWithID(c, attributes);
@@ -429,8 +497,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
}
- private void startElement(FONode node) {
- startElement(node, new AttributesImpl());
+ private StructureTreeElement startElement(FONode node) {
+ return startElement(node, new AttributesImpl());
}
private void startElementWithID(FONode node) {
@@ -443,7 +511,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
addRole((CommonAccessibilityHolder) node, attributes);
}
node.setStructureTreeElement(
- structureTreeEventHandler.startReferencedNode(localName, attributes));
+ structureTreeEventHandler.startReferencedNode(localName, attributes,
+ node.getParent().getStructureTreeElement()));
}
private void startElementWithIDAndAltText(AbstractGraphics node) {
@@ -453,7 +522,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
addAttribute(attributes, ExtensionElementMapping.URI, "alt-text",
ExtensionElementMapping.STANDARD_PREFIX, node.getAltText());
node.setStructureTreeElement(
- structureTreeEventHandler.startImageNode(localName, attributes));
+ structureTreeEventHandler.startImageNode(localName, attributes,
+ node.getParent().getStructureTreeElement()));
}
private StructureTreeElement startElement(FONode node, AttributesImpl attributes) {
@@ -461,7 +531,8 @@ class StructureTreeEventTrigger extends FOEventHandler {
if (node instanceof CommonAccessibilityHolder) {
addRole((CommonAccessibilityHolder) node, attributes);
}
- return structureTreeEventHandler.startNode(localName, attributes);
+ return structureTreeEventHandler.startNode(localName, attributes,
+ node.getParent().getStructureTreeElement());
}
private void addNoNamespaceAttribute(AttributesImpl attributes, String name, String value) {