Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

AbstractXMLRenderer.java 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  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.render.xml;
  19. import java.awt.geom.Rectangle2D;
  20. import java.io.IOException;
  21. import java.io.OutputStream;
  22. import java.util.List;
  23. import javax.xml.transform.TransformerConfigurationException;
  24. import javax.xml.transform.sax.SAXTransformerFactory;
  25. import javax.xml.transform.sax.TransformerHandler;
  26. import javax.xml.transform.stream.StreamResult;
  27. import org.xml.sax.Attributes;
  28. import org.xml.sax.ContentHandler;
  29. import org.xml.sax.SAXException;
  30. import org.xml.sax.ext.LexicalHandler;
  31. import org.xml.sax.helpers.AttributesImpl;
  32. import org.apache.xmlgraphics.util.QName;
  33. import org.apache.fop.apps.FOUserAgent;
  34. import org.apache.fop.area.BookmarkData;
  35. import org.apache.fop.area.OffDocumentExtensionAttachment;
  36. import org.apache.fop.area.OffDocumentItem;
  37. import org.apache.fop.area.PageViewport;
  38. import org.apache.fop.fo.extensions.ExtensionAttachment;
  39. import org.apache.fop.render.PrintRenderer;
  40. import org.apache.fop.render.RendererContext;
  41. /** Abstract xml renderer base class. */
  42. public abstract class AbstractXMLRenderer extends PrintRenderer {
  43. /**
  44. * @param userAgent the user agent that contains configuration details. This cannot be null.
  45. */
  46. public AbstractXMLRenderer(FOUserAgent userAgent) {
  47. super(userAgent);
  48. }
  49. /** Main namespace in use. */
  50. public static final String NS = "";
  51. /** CDATA type */
  52. public static final String CDATA = "CDATA";
  53. /** An empty Attributes object used when no attributes are needed. */
  54. public static final Attributes EMPTY_ATTS = new AttributesImpl();
  55. /** AttributesImpl instance that can be used during XML generation. */
  56. protected AttributesImpl atts = new AttributesImpl();
  57. /** ContentHandler that the generated XML is written to */
  58. protected ContentHandler handler;
  59. /** The OutputStream to write the generated XML to. */
  60. protected OutputStream out;
  61. /** The renderer context. */
  62. protected RendererContext context;
  63. /** A list of ExtensionAttachements received through processOffDocumentItem() */
  64. protected List extensionAttachments;
  65. /**
  66. * Handles SAXExceptions.
  67. * @param saxe the SAXException to handle
  68. */
  69. protected void handleSAXException(SAXException saxe) {
  70. throw new RuntimeException(saxe.getMessage());
  71. }
  72. /**
  73. * Handles page extension attachments
  74. * @param page the page viewport
  75. */
  76. protected void handlePageExtensionAttachments(PageViewport page) {
  77. handleExtensionAttachments(page.getExtensionAttachments());
  78. }
  79. /**
  80. * Writes a comment to the generated XML.
  81. * @param comment the comment
  82. */
  83. protected void comment(String comment) {
  84. if (handler instanceof LexicalHandler) {
  85. try {
  86. ((LexicalHandler) handler).comment(comment.toCharArray(), 0, comment.length());
  87. } catch (SAXException saxe) {
  88. handleSAXException(saxe);
  89. }
  90. }
  91. }
  92. /**
  93. * Starts a new element (without attributes).
  94. * @param tagName tag name of the element
  95. */
  96. protected void startElement(String tagName) {
  97. startElement(tagName, EMPTY_ATTS);
  98. }
  99. /**
  100. * Starts a new element.
  101. * @param tagName tag name of the element
  102. * @param atts attributes to add
  103. */
  104. protected void startElement(String tagName, Attributes atts) {
  105. try {
  106. handler.startElement(NS, tagName, tagName, atts);
  107. } catch (SAXException saxe) {
  108. handleSAXException(saxe);
  109. }
  110. }
  111. /**
  112. * Ends an element.
  113. * @param tagName tag name of the element
  114. */
  115. protected void endElement(String tagName) {
  116. try {
  117. handler.endElement(NS, tagName, tagName);
  118. } catch (SAXException saxe) {
  119. handleSAXException(saxe);
  120. }
  121. }
  122. /**
  123. * Sends plain text to the XML
  124. * @param text the text
  125. */
  126. protected void characters(String text) {
  127. try {
  128. char[] ca = text.toCharArray();
  129. handler.characters(ca, 0, ca.length);
  130. } catch (SAXException saxe) {
  131. handleSAXException(saxe);
  132. }
  133. }
  134. /**
  135. * Adds a new attribute to the protected member variable "atts".
  136. * @param name name of the attribute
  137. * @param value value of the attribute
  138. */
  139. protected void addAttribute(String name, String value) {
  140. atts.addAttribute(NS, name, name, CDATA, value);
  141. }
  142. /**
  143. * Adds a new attribute to the protected member variable "atts".
  144. * @param name name of the attribute
  145. * @param value value of the attribute
  146. */
  147. protected void addAttribute(QName name, String value) {
  148. atts.addAttribute(name.getNamespaceURI(), name.getLocalName(), name.getQName(),
  149. CDATA, value);
  150. }
  151. /**
  152. * Adds a new attribute to the protected member variable "atts".
  153. * @param name name of the attribute
  154. * @param value value of the attribute
  155. */
  156. protected void addAttribute(String name, int value) {
  157. addAttribute(name, Integer.toString(value));
  158. }
  159. private String createString(Rectangle2D rect) {
  160. return "" + (int) rect.getX() + " " + (int) rect.getY() + " "
  161. + (int) rect.getWidth() + " " + (int) rect.getHeight();
  162. }
  163. /**
  164. * Adds a new attribute to the protected member variable "atts".
  165. * @param name name of the attribute
  166. * @param rect a Rectangle2D to format and use as attribute value
  167. */
  168. protected void addAttribute(String name, Rectangle2D rect) {
  169. addAttribute(name, createString(rect));
  170. }
  171. /** {@inheritDoc} */
  172. public void startRenderer(OutputStream outputStream)
  173. throws IOException {
  174. if (this.handler == null) {
  175. SAXTransformerFactory factory
  176. = (SAXTransformerFactory)SAXTransformerFactory.newInstance();
  177. try {
  178. TransformerHandler transformerHandler = factory.newTransformerHandler();
  179. setContentHandler(transformerHandler);
  180. StreamResult res = new StreamResult(outputStream);
  181. transformerHandler.setResult(res);
  182. } catch (TransformerConfigurationException tce) {
  183. throw new RuntimeException(tce.getMessage());
  184. }
  185. this.out = outputStream;
  186. }
  187. try {
  188. handler.startDocument();
  189. } catch (SAXException saxe) {
  190. handleSAXException(saxe);
  191. }
  192. }
  193. /** {@inheritDoc} */
  194. public void stopRenderer() throws IOException {
  195. try {
  196. handler.endDocument();
  197. } catch (SAXException saxe) {
  198. handleSAXException(saxe);
  199. }
  200. if (this.out != null) {
  201. this.out.flush();
  202. }
  203. }
  204. /** {@inheritDoc} */
  205. public void processOffDocumentItem(OffDocumentItem oDI) {
  206. if (oDI instanceof BookmarkData) {
  207. renderBookmarkTree((BookmarkData) oDI);
  208. } else if (oDI instanceof OffDocumentExtensionAttachment) {
  209. ExtensionAttachment attachment = ((OffDocumentExtensionAttachment)oDI).getAttachment();
  210. if (extensionAttachments == null) {
  211. extensionAttachments = new java.util.ArrayList();
  212. }
  213. extensionAttachments.add(attachment);
  214. } else {
  215. String warn = "Ignoring OffDocumentItem: " + oDI;
  216. log.warn(warn);
  217. }
  218. }
  219. /** Handle document extension attachments. */
  220. protected void handleDocumentExtensionAttachments() {
  221. if (extensionAttachments != null && extensionAttachments.size() > 0) {
  222. handleExtensionAttachments(extensionAttachments);
  223. extensionAttachments.clear();
  224. }
  225. }
  226. /**
  227. * Sets an outside TransformerHandler to use instead of the default one
  228. * create in this class in startRenderer().
  229. * @param handler Overriding TransformerHandler
  230. */
  231. public void setContentHandler(ContentHandler handler) {
  232. this.handler = handler;
  233. }
  234. /**
  235. * Handles a list of extension attachments
  236. * @param attachments a list of extension attachments
  237. */
  238. protected abstract void handleExtensionAttachments(List attachments);
  239. /**
  240. * Renders a bookmark tree
  241. * @param odi the bookmark data
  242. */
  243. protected abstract void renderBookmarkTree(BookmarkData odi);
  244. }