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.

PDFExtensionHandler.java 10KB

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.render.pdf.extensions;
  19. import java.util.Stack;
  20. import org.xml.sax.Attributes;
  21. import org.xml.sax.SAXException;
  22. import org.xml.sax.helpers.AttributesImpl;
  23. import org.xml.sax.helpers.DefaultHandler;
  24. import org.apache.commons.logging.Log;
  25. import org.apache.commons.logging.LogFactory;
  26. import org.apache.fop.util.ContentHandlerFactory;
  27. import org.apache.fop.util.ContentHandlerFactory.ObjectBuiltListener;
  28. /**
  29. * ContentHandler (parser) for restoring PDF extension objects from XML.
  30. */
  31. public class PDFExtensionHandler extends DefaultHandler implements ContentHandlerFactory.ObjectSource {
  32. /** Logger instance */
  33. protected static final Log log = LogFactory.getLog(PDFExtensionHandler.class);
  34. private PDFExtensionAttachment returnedObject;
  35. private ObjectBuiltListener listener;
  36. // PDFEmbeddedFileAttachment related state
  37. private Attributes lastAttributes;
  38. // PDFDictionaryAttachment related
  39. private Stack<PDFCollectionExtension> collections = new Stack<PDFCollectionExtension>();
  40. private boolean captureContent;
  41. private StringBuffer characters;
  42. @Override
  43. public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
  44. if (PDFExtensionAttachment.CATEGORY.equals(uri)) {
  45. if (localName.equals(PDFEmbeddedFileAttachment.ELEMENT)) {
  46. lastAttributes = new AttributesImpl(attributes);
  47. } else if (PDFDictionaryType.Action.elementName().equals(localName)) {
  48. PDFActionExtension action = new PDFActionExtension();
  49. String id = attributes.getValue(PDFDictionaryElement.ATT_ID);
  50. if (id != null) {
  51. action.setProperty(PDFDictionaryExtension.PROPERTY_ID, id);
  52. }
  53. String type = attributes.getValue(PDFActionElement.ATT_TYPE);
  54. if (type != null) {
  55. action.setProperty(PDFActionExtension.PROPERTY_TYPE, type);
  56. }
  57. collections.push(action);
  58. } else if (PDFObjectType.Array.elementName().equals(localName)) {
  59. PDFArrayExtension array = new PDFArrayExtension();
  60. String key = attributes.getValue(PDFCollectionEntryElement.ATT_KEY);
  61. if (key != null) {
  62. array.setKey(key);
  63. }
  64. collections.push(array);
  65. } else if (PDFDictionaryType.Catalog.elementName().equals(localName)) {
  66. PDFCatalogExtension catalog = new PDFCatalogExtension();
  67. collections.push(catalog);
  68. } else if (PDFDictionaryType.Dictionary.elementName().equals(localName)) {
  69. PDFDictionaryExtension dictionary = new PDFDictionaryExtension();
  70. String key = attributes.getValue(PDFCollectionEntryElement.ATT_KEY);
  71. if (key != null) {
  72. dictionary.setKey(key);
  73. }
  74. collections.push(dictionary);
  75. } else if (PDFDictionaryType.Layer.elementName().equals(localName)) {
  76. PDFLayerExtension layer = new PDFLayerExtension();
  77. String id = attributes.getValue(PDFDictionaryElement.ATT_ID);
  78. if (id != null) {
  79. layer.setProperty(PDFDictionaryExtension.PROPERTY_ID, id);
  80. }
  81. collections.push(layer);
  82. } else if (PDFDictionaryType.Navigator.elementName().equals(localName)) {
  83. PDFNavigatorExtension navigator = new PDFNavigatorExtension();
  84. String id = attributes.getValue(PDFDictionaryElement.ATT_ID);
  85. if (id != null) {
  86. navigator.setProperty(PDFDictionaryExtension.PROPERTY_ID, id);
  87. }
  88. collections.push(navigator);
  89. } else if (PDFDictionaryType.Page.elementName().equals(localName)) {
  90. PDFPageExtension page = new PDFPageExtension();
  91. String pageNumbers = attributes.getValue(PDFPageElement.ATT_PAGE_NUMBERS);
  92. if (pageNumbers != null) {
  93. page.setProperty(PDFPageExtension.PROPERTY_PAGE_NUMBERS, pageNumbers);
  94. }
  95. collections.push(page);
  96. } else if (PDFDictionaryType.Info.elementName().equals(localName)) {
  97. PDFDocumentInformationExtension info = new PDFDocumentInformationExtension();
  98. collections.push(info);
  99. } else if (PDFObjectType.hasValueOfElementName(localName)) {
  100. PDFCollectionEntryExtension entry;
  101. if (PDFObjectType.Reference.elementName().equals(localName)) {
  102. entry = new PDFReferenceExtension();
  103. } else {
  104. entry = new PDFCollectionEntryExtension(PDFObjectType.valueOfElementName(localName));
  105. }
  106. String key = attributes.getValue(PDFCollectionEntryElement.ATT_KEY);
  107. if (key != null) {
  108. entry.setKey(key);
  109. }
  110. if (entry instanceof PDFReferenceExtension) {
  111. String refid = attributes.getValue(PDFReferenceElement.ATT_REFID);
  112. if (refid != null) {
  113. ((PDFReferenceExtension) entry).setReferenceId(refid);
  114. }
  115. }
  116. if (!collections.empty()) {
  117. PDFCollectionExtension collection = collections.peek();
  118. collection.addEntry(entry);
  119. if (!(entry instanceof PDFReferenceExtension)) {
  120. captureContent = true;
  121. }
  122. }
  123. } else {
  124. throw new SAXException("Unhandled element " + localName + " in namespace: " + uri);
  125. }
  126. } else {
  127. log.warn("Unhandled element " + localName + " in namespace: " + uri);
  128. }
  129. }
  130. @Override
  131. public void characters(char[] data, int start, int length) throws SAXException {
  132. if (captureContent) {
  133. if (characters == null) {
  134. characters = new StringBuffer((length < 16) ? 16 : length);
  135. }
  136. characters.append(data, start, length);
  137. }
  138. }
  139. @Override
  140. public void endElement(String uri, String localName, String qName) throws SAXException {
  141. if (PDFExtensionAttachment.CATEGORY.equals(uri)) {
  142. if (PDFEmbeddedFileAttachment.ELEMENT.equals(localName)) {
  143. String name = lastAttributes.getValue("name");
  144. String src = lastAttributes.getValue("src");
  145. String desc = lastAttributes.getValue("description");
  146. this.lastAttributes = null;
  147. this.returnedObject = new PDFEmbeddedFileAttachment(name, src, desc);
  148. } else if (PDFDictionaryType.hasValueOfElementName(localName)) {
  149. if (!collections.empty() && (collections.peek() instanceof PDFDictionaryExtension)) {
  150. PDFDictionaryExtension dictionary = (PDFDictionaryExtension) collections.pop();
  151. if (!collections.empty()) {
  152. PDFCollectionExtension collectionOuter = collections.peek();
  153. collectionOuter.addEntry(dictionary);
  154. } else if (dictionary.getDictionaryType() != PDFDictionaryType.Dictionary) {
  155. this.returnedObject = new PDFDictionaryAttachment(dictionary);
  156. } else {
  157. throw new SAXException(
  158. new IllegalStateException("generic dictionary not permitted at outer level"));
  159. }
  160. } else {
  161. throw new SAXException(new IllegalStateException("collections stack is empty or not a dictionary"));
  162. }
  163. } else if (PDFObjectType.Array.elementName().equals(localName)) {
  164. if (!collections.empty() && (collections.peek() instanceof PDFArrayExtension)) {
  165. PDFArrayExtension array = (PDFArrayExtension) collections.pop();
  166. if (!collections.empty()) {
  167. PDFCollectionExtension collectionOuter = collections.peek();
  168. collectionOuter.addEntry(array);
  169. } else {
  170. throw new SAXException(new IllegalStateException("array not permitted at outer level"));
  171. }
  172. } else {
  173. throw new SAXException(new IllegalStateException("collections stack is empty or not an array"));
  174. }
  175. } else if (PDFObjectType.hasValueOfElementName(localName)) {
  176. if (!collections.empty()) {
  177. PDFCollectionExtension collection = collections.peek();
  178. PDFCollectionEntryExtension entry = collection.getLastEntry();
  179. if (entry != null) {
  180. if (characters != null) {
  181. entry.setValue(characters.toString());
  182. characters = null;
  183. }
  184. } else {
  185. throw new SAXException(new IllegalStateException("no current entry"));
  186. }
  187. } else {
  188. throw new SAXException(new IllegalStateException("entry not permitted at outer level"));
  189. }
  190. }
  191. }
  192. captureContent = false;
  193. }
  194. @Override
  195. public void endDocument() throws SAXException {
  196. if (listener != null) {
  197. listener.notifyObjectBuilt(getObject());
  198. }
  199. }
  200. public Object getObject() {
  201. return returnedObject;
  202. }
  203. public void setObjectBuiltListener(ObjectBuiltListener listener) {
  204. this.listener = listener;
  205. }
  206. }