Skip to content

Commit 6779aa1

Browse files
FOP-3272: Optimise memory usage for accessibility
1 parent 794684a commit 6779aa1

File tree

3 files changed

+45
-21
lines changed

3 files changed

+45
-21
lines changed

fop-core/src/main/java/org/apache/fop/accessibility/fo/Event.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.apache.fop.fo.FOEventHandler;
2525

2626
class Event {
27-
private List<Event> children = new ArrayList<Event>();
27+
private List<Event> children;
2828
protected FOEventHandler eventHandler;
2929
protected Event parent;
3030
protected boolean hasContent;
@@ -37,6 +37,12 @@ public Event(Event parent) {
3737
this.parent = parent;
3838
}
3939

40+
private void init() {
41+
if (children == null) {
42+
children = new ArrayList<>();
43+
}
44+
}
45+
4046
public void run() {
4147
if (hasContent()) {
4248
for (Event e : children) {
@@ -47,6 +53,7 @@ public void run() {
4753
}
4854

4955
private boolean hasContent() {
56+
init();
5057
for (Event e : children) {
5158
if (e.hasContent()) {
5259
return true;
@@ -56,6 +63,7 @@ private boolean hasContent() {
5663
}
5764

5865
public void add(Event child) {
66+
init();
5967
children.add(child);
6068
}
6169
}

fop-core/src/main/java/org/apache/fop/render/intermediate/IFStructureTreeBuilder.java

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.apache.fop.accessibility.StructureTree2SAXEventAdapter;
3333
import org.apache.fop.accessibility.StructureTreeElement;
3434
import org.apache.fop.accessibility.StructureTreeEventHandler;
35+
import org.apache.fop.fo.FOElementMapping;
3536
import org.apache.fop.fo.extensions.InternalElementMapping;
3637
import org.apache.fop.util.XMLConstants;
3738
import org.apache.fop.util.XMLUtil;
@@ -69,31 +70,44 @@ private abstract static class Event {
6970
}
7071

7172
private abstract static class Element extends SAXEventRecorder.Event {
72-
73-
protected final String uri;
73+
private final boolean isFONamespace;
7474
protected final String localName;
75-
protected final String qName;
7675

7776
private Element(String uri, String localName, String qName) {
78-
this.uri = uri;
7977
this.localName = localName;
80-
this.qName = qName;
78+
isFONamespace = FOElementMapping.URI.equals(uri);
79+
if (!isFONamespace && !IFConstants.NAMESPACE.equals(uri)) {
80+
throw new UnsupportedOperationException();
81+
}
82+
}
83+
84+
protected String getQName() {
85+
if (isFONamespace) {
86+
return "fo:" + localName;
87+
}
88+
return localName;
89+
}
90+
91+
protected String getURI() {
92+
if (isFONamespace) {
93+
return FOElementMapping.URI;
94+
}
95+
return IFConstants.NAMESPACE;
8196
}
8297
}
8398

8499
private static final class StartElement extends SAXEventRecorder.Element {
85-
86100
private final Attributes attributes;
87101

88102
private StartElement(String uri, String localName, String qName,
89103
Attributes attributes) {
90104
super(uri, localName, qName);
91-
this.attributes = attributes;
105+
this.attributes = new AttributesImpl(attributes);
92106
}
93107

94108
@Override
95109
void replay(ContentHandler handler) throws SAXException {
96-
handler.startElement(uri, localName, qName, attributes);
110+
handler.startElement(getURI(), localName, getQName(), attributes);
97111
}
98112
}
99113

@@ -105,7 +119,7 @@ private EndElement(String uri, String localName, String qName) {
105119

106120
@Override
107121
void replay(ContentHandler handler) throws SAXException {
108-
handler.endElement(uri, localName, qName);
122+
handler.endElement(getURI(), localName, getQName());
109123
}
110124
}
111125

fop-core/src/test/java/org/apache/fop/render/intermediate/SAXEventRecorderTestCase.java

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919

2020
package org.apache.fop.render.intermediate;
2121

22-
2322
import org.junit.Before;
2423
import org.junit.Test;
2524
import org.mockito.InOrder;
@@ -28,10 +27,13 @@
2827
import org.xml.sax.SAXException;
2928
import org.xml.sax.helpers.AttributesImpl;
3029

30+
import static org.mockito.ArgumentMatchers.any;
31+
import static org.mockito.ArgumentMatchers.eq;
3132
import static org.mockito.Mockito.inOrder;
3233
import static org.mockito.Mockito.mock;
3334
import static org.mockito.Mockito.verify;
3435

36+
import org.apache.fop.fo.FOElementMapping;
3537
import org.apache.fop.render.intermediate.IFStructureTreeBuilder.SAXEventRecorder;
3638
import org.apache.fop.util.XMLUtil;
3739

@@ -40,7 +42,7 @@
4042
*/
4143
public class SAXEventRecorderTestCase {
4244

43-
private static final String URI = "http://www.example.com/";
45+
private static final String URI = FOElementMapping.URI;
4446

4547
private SAXEventRecorder sut;
4648

@@ -52,19 +54,19 @@ public void setUp() {
5254
@Test
5355
public void testStartEvent() throws SAXException {
5456
final String localName = "element";
55-
final String qName = "prefix:" + localName;
57+
final String qName = "fo:" + localName;
5658
final Attributes attributes = new AttributesImpl();
5759

5860
sut.startElement(URI, localName, qName, attributes);
5961
ContentHandler handler = mock(ContentHandler.class);
6062
sut.replay(handler);
61-
verify(handler).startElement(URI, localName, qName, attributes);
63+
verify(handler).startElement(eq(URI), eq(localName), eq(qName), any(Attributes.class));
6264
}
6365

6466
@Test
6567
public void testEndEvent() throws SAXException {
6668
final String localName = "element";
67-
final String qName = "prefix:" + localName;
69+
final String qName = "fo:" + localName;
6870
sut.endElement(URI, localName, qName);
6971
ContentHandler handler = mock(ContentHandler.class);
7072
sut.replay(handler);
@@ -94,14 +96,14 @@ public void testEndPrefixMapping() throws SAXException {
9496
@Test
9597
public void completeTest() throws SAXException {
9698
final String localName1 = "element";
97-
final String qName1 = "prefix:" + localName1;
99+
final String qName1 = "fo:" + localName1;
98100
final Attributes attributes1 = createAttributes(URI, localName1, qName1, "value-1");
99101
final String localName2 = "element2";
100-
final String qName2 = "prefix:" + localName2;
102+
final String qName2 = "fo:" + localName2;
101103
final Attributes attributes2 = createAttributes(URI, localName2, qName2, "value-2");
102104
final ContentHandler handler = mock(ContentHandler.class);
103-
final String extensionUrl = "http://www.example.com/extension";
104-
final String extensionPrefix = "ext";
105+
final String extensionUrl = URI;
106+
final String extensionPrefix = "fo";
105107

106108
sut.startPrefixMapping(extensionPrefix, extensionUrl);
107109
sut.startElement(URI, localName1, qName1, attributes1);
@@ -114,8 +116,8 @@ public void completeTest() throws SAXException {
114116

115117
InOrder inOrder = inOrder(handler);
116118
inOrder.verify(handler).startPrefixMapping(extensionPrefix, extensionUrl);
117-
inOrder.verify(handler).startElement(URI, localName1, qName1, attributes1);
118-
inOrder.verify(handler).startElement(URI, localName2, qName2, attributes2);
119+
inOrder.verify(handler).startElement(eq(URI), eq(localName1), eq(qName1), any(Attributes.class));
120+
inOrder.verify(handler).startElement(eq(URI), eq(localName2), eq(qName2), any(Attributes.class));
119121
inOrder.verify(handler).endElement(URI, localName2, qName2);
120122
inOrder.verify(handler).endElement(URI, localName1, qName1);
121123
inOrder.verify(handler).endPrefixMapping(extensionPrefix);

0 commit comments

Comments
 (0)