You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

FO2StructureTreeConverterTestCase.java 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.accessibility.fo;
  19. import static org.junit.Assert.assertTrue;
  20. import java.io.ByteArrayInputStream;
  21. import java.io.ByteArrayOutputStream;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import javax.xml.transform.Result;
  25. import javax.xml.transform.Source;
  26. import javax.xml.transform.Transformer;
  27. import javax.xml.transform.TransformerConfigurationException;
  28. import javax.xml.transform.TransformerException;
  29. import javax.xml.transform.TransformerFactory;
  30. import javax.xml.transform.TransformerFactoryConfigurationError;
  31. import javax.xml.transform.dom.DOMResult;
  32. import javax.xml.transform.sax.SAXTransformerFactory;
  33. import javax.xml.transform.sax.TransformerHandler;
  34. import javax.xml.transform.stream.StreamResult;
  35. import javax.xml.transform.stream.StreamSource;
  36. import org.custommonkey.xmlunit.Diff;
  37. import org.junit.Test;
  38. import org.w3c.dom.Document;
  39. import org.xml.sax.SAXException;
  40. import org.xml.sax.helpers.AttributesImpl;
  41. import org.apache.fop.accessibility.StructureTree2SAXEventAdapter;
  42. import org.apache.fop.accessibility.StructureTreeEventHandler;
  43. import org.apache.fop.apps.FOPException;
  44. import org.apache.fop.apps.FOUserAgent;
  45. import org.apache.fop.fo.FODocumentParser;
  46. import org.apache.fop.fo.FODocumentParser.FOEventHandlerFactory;
  47. import org.apache.fop.fo.FOEventHandler;
  48. import org.apache.fop.fo.LoadingException;
  49. import org.apache.fop.fotreetest.DummyFOEventHandler;
  50. public class FO2StructureTreeConverterTestCase {
  51. private interface FOLoader {
  52. InputStream getFoInputStream();
  53. }
  54. private static final String STRUCTURE_TREE_SEQUENCE_NAME = "structure-tree-sequence";
  55. private FOLoader foLoader;
  56. @Test
  57. public void testCompleteDocument() throws Exception {
  58. foLoader = new FOLoader() {
  59. public InputStream getFoInputStream() {
  60. return getResource("/org/apache/fop/fo/complete_document.fo");
  61. }
  62. };
  63. testConverter();
  64. }
  65. @Test
  66. public void testTableFooters() throws Exception {
  67. foLoader = new FOLoader() {
  68. public InputStream getFoInputStream() {
  69. return getResource("table-footers.fo");
  70. }
  71. };
  72. testConverter();
  73. }
  74. @Test
  75. public void testCompleteContentWrappedInTableFooter() throws Exception {
  76. Source xslt = new StreamSource(getResource("wrapCompleteDocumentInTableFooter.xsl"));
  77. Transformer transformer = createTransformer(xslt);
  78. InputStream originalFO = getResource("/org/apache/fop/fo/complete_document.fo");
  79. ByteArrayOutputStream transformedFoOutput = new ByteArrayOutputStream();
  80. transformer.transform(new StreamSource(originalFO), new StreamResult(transformedFoOutput));
  81. final byte[] transformedFoOutputBytes = transformedFoOutput.toByteArray();
  82. foLoader = new FOLoader() {
  83. public InputStream getFoInputStream() {
  84. return new ByteArrayInputStream(transformedFoOutputBytes);
  85. }
  86. };
  87. testConverter();
  88. }
  89. private Transformer createTransformer(Source xslt) throws TransformerFactoryConfigurationError,
  90. TransformerConfigurationException {
  91. TransformerFactory transformerFactory = TransformerFactory.newInstance();
  92. return transformerFactory.newTransformer(xslt);
  93. }
  94. private static InputStream getResource(String name) {
  95. return FO2StructureTreeConverterTestCase.class.getResourceAsStream(name);
  96. }
  97. private void testConverter() throws Exception {
  98. DOMResult expectedStructureTree = loadExpectedStructureTree();
  99. DOMResult actualStructureTree = buildActualStructureTree();
  100. final Diff diff = createDiff(expectedStructureTree, actualStructureTree);
  101. assertTrue(diff.toString(), diff.identical());
  102. }
  103. private DOMResult loadExpectedStructureTree() {
  104. DOMResult expectedStructureTree = new DOMResult();
  105. InputStream xslt = getResource("fo2StructureTree.xsl");
  106. runXSLT(xslt, foLoader.getFoInputStream(), expectedStructureTree);
  107. return expectedStructureTree;
  108. }
  109. private static void runXSLT(InputStream xslt, InputStream doc, Result result) {
  110. Source fo = new StreamSource(doc);
  111. try {
  112. Transformer transformer = TransformerFactory.newInstance()
  113. .newTransformer(new StreamSource(xslt));
  114. transformer.transform(fo, result);
  115. } catch (TransformerConfigurationException e) {
  116. throw new RuntimeException(e);
  117. } catch (TransformerException e) {
  118. throw new RuntimeException(e);
  119. } finally {
  120. closeStream(xslt);
  121. closeStream(doc);
  122. }
  123. }
  124. private static void closeStream(InputStream stream) {
  125. try {
  126. stream.close();
  127. } catch (IOException e) {
  128. throw new RuntimeException(e);
  129. }
  130. }
  131. private DOMResult buildActualStructureTree() throws Exception {
  132. DOMResult actualStructureTree = new DOMResult();
  133. createStructureTreeFromDocument(foLoader.getFoInputStream(), actualStructureTree);
  134. return actualStructureTree;
  135. }
  136. private static void createStructureTreeFromDocument(InputStream foInputStream,
  137. Result result) throws Exception {
  138. TransformerHandler tHandler = createTransformerHandler(result);
  139. startStructureTreeSequence(tHandler);
  140. StructureTreeEventHandler structureTreeEventHandler
  141. = StructureTree2SAXEventAdapter.newInstance(tHandler);
  142. FODocumentParser documentParser = createDocumentParser(structureTreeEventHandler);
  143. FOUserAgent userAgent = createFOUserAgent(documentParser);
  144. parseDocument(foInputStream, documentParser, userAgent);
  145. endStructureTreeSequence(tHandler);
  146. }
  147. private static TransformerHandler createTransformerHandler(Result domResult)
  148. throws TransformerConfigurationException, TransformerFactoryConfigurationError {
  149. SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
  150. TransformerHandler transformerHandler = factory.newTransformerHandler();
  151. transformerHandler.setResult(domResult);
  152. return transformerHandler;
  153. }
  154. private static void startStructureTreeSequence(TransformerHandler tHandler) throws SAXException {
  155. tHandler.startDocument();
  156. tHandler.startElement("", STRUCTURE_TREE_SEQUENCE_NAME, STRUCTURE_TREE_SEQUENCE_NAME,
  157. new AttributesImpl());
  158. }
  159. private static FODocumentParser createDocumentParser(
  160. final StructureTreeEventHandler structureTreeEventHandler) {
  161. return FODocumentParser.newInstance(new FOEventHandlerFactory() {
  162. public FOEventHandler newFOEventHandler(FOUserAgent foUserAgent) {
  163. return new FO2StructureTreeConverter(structureTreeEventHandler,
  164. new DummyFOEventHandler(foUserAgent));
  165. }
  166. });
  167. }
  168. private static FOUserAgent createFOUserAgent(FODocumentParser documentParser) {
  169. FOUserAgent userAgent = documentParser.createFOUserAgent();
  170. userAgent.setAccessibility(true);
  171. return userAgent;
  172. }
  173. private static void parseDocument(InputStream foInputStream, FODocumentParser documentParser,
  174. FOUserAgent userAgent) throws FOPException, LoadingException {
  175. try {
  176. documentParser.parse(foInputStream, userAgent);
  177. } finally {
  178. closeStream(foInputStream);
  179. }
  180. }
  181. private static void endStructureTreeSequence(TransformerHandler tHandler) throws SAXException {
  182. tHandler.endElement("", STRUCTURE_TREE_SEQUENCE_NAME, STRUCTURE_TREE_SEQUENCE_NAME);
  183. tHandler.endDocument();
  184. }
  185. private static Diff createDiff(DOMResult expected, DOMResult actual) {
  186. Diff diff = new Diff(getDocument(expected), getDocument(actual));
  187. return diff;
  188. }
  189. private static Document getDocument(DOMResult result) {
  190. return (Document) result.getNode();
  191. }
  192. }