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.

PDFRendererConfig.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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;
  19. import java.net.URI;
  20. import java.net.URISyntaxException;
  21. import java.util.ArrayList;
  22. import java.util.EnumMap;
  23. import java.util.HashMap;
  24. import java.util.List;
  25. import java.util.Map;
  26. import org.apache.avalon.framework.configuration.Configuration;
  27. import org.apache.avalon.framework.configuration.ConfigurationException;
  28. import org.apache.commons.logging.Log;
  29. import org.apache.commons.logging.LogFactory;
  30. import org.apache.fop.apps.FOPException;
  31. import org.apache.fop.apps.FOUserAgent;
  32. import org.apache.fop.apps.MimeConstants;
  33. import org.apache.fop.apps.io.InternalResourceResolver;
  34. import org.apache.fop.fonts.DefaultFontConfig;
  35. import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
  36. import org.apache.fop.pdf.PDFAMode;
  37. import org.apache.fop.pdf.PDFEncryptionParams;
  38. import org.apache.fop.pdf.PDFFilterList;
  39. import org.apache.fop.pdf.PDFXMode;
  40. import org.apache.fop.pdf.Version;
  41. import org.apache.fop.render.RendererConfig;
  42. import org.apache.fop.util.LogUtil;
  43. import static org.apache.fop.render.pdf.PDFRendererConfigOption.DISABLE_SRGB_COLORSPACE;
  44. import static org.apache.fop.render.pdf.PDFRendererConfigOption.ENCRYPTION_LENGTH;
  45. import static org.apache.fop.render.pdf.PDFRendererConfigOption.ENCRYPTION_PARAMS;
  46. import static org.apache.fop.render.pdf.PDFRendererConfigOption.FILTER_LIST;
  47. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_ACCESSCONTENT;
  48. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_ANNOTATIONS;
  49. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_ASSEMBLEDOC;
  50. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_COPY_CONTENT;
  51. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_EDIT_CONTENT;
  52. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_FILLINFORMS;
  53. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_PRINT;
  54. import static org.apache.fop.render.pdf.PDFRendererConfigOption.NO_PRINTHQ;
  55. import static org.apache.fop.render.pdf.PDFRendererConfigOption.OUTPUT_PROFILE;
  56. import static org.apache.fop.render.pdf.PDFRendererConfigOption.OWNER_PASSWORD;
  57. import static org.apache.fop.render.pdf.PDFRendererConfigOption.PDF_A_MODE;
  58. import static org.apache.fop.render.pdf.PDFRendererConfigOption.PDF_X_MODE;
  59. import static org.apache.fop.render.pdf.PDFRendererConfigOption.USER_PASSWORD;
  60. import static org.apache.fop.render.pdf.PDFRendererConfigOption.VERSION;
  61. /**
  62. * The PDF renderer configuration data object.
  63. */
  64. public final class PDFRendererConfig implements RendererConfig {
  65. private static final Log LOG = LogFactory.getLog(PDFRendererConfig.class);
  66. private final Map<PDFRendererConfigOption, Object> configOptions
  67. = new EnumMap<PDFRendererConfigOption, Object>(PDFRendererConfigOption.class);
  68. private final DefaultFontConfig fontConfig;
  69. private PDFRendererConfig(DefaultFontConfig fontConfig) {
  70. this.fontConfig = fontConfig;
  71. }
  72. public DefaultFontConfig getFontInfoConfig() {
  73. return fontConfig;
  74. }
  75. public Map<String, List<String>> getFilterMap() {
  76. return (Map<String, List<String>>) configOptions.get(FILTER_LIST);
  77. }
  78. public PDFAMode getPDFAMode() {
  79. return (PDFAMode) configOptions.get(PDF_A_MODE);
  80. }
  81. public PDFXMode getPDFXMode() {
  82. return (PDFXMode) configOptions.get(PDF_X_MODE);
  83. }
  84. public PDFEncryptionParams getEncryptionParameters() {
  85. return (PDFEncryptionParams) configOptions.get(ENCRYPTION_PARAMS);
  86. }
  87. public URI getOutputProfileURI() {
  88. return (URI) configOptions.get(OUTPUT_PROFILE);
  89. }
  90. public Boolean getDisableSRGBColorSpace() {
  91. return (Boolean) configOptions.get(DISABLE_SRGB_COLORSPACE);
  92. }
  93. public Version getPDFVersion() {
  94. String pdfVersion = (String) configOptions.get(VERSION);
  95. return pdfVersion == null ? null : Version.getValueOf(pdfVersion);
  96. }
  97. /**
  98. * The PDF renderer configuration data parser.
  99. */
  100. public static final class PDFRendererConfigParser implements RendererConfigParser {
  101. public PDFRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
  102. boolean strict = userAgent != null ? userAgent.validateUserConfigStrictly() : false;
  103. return new ParserHelper(cfg, userAgent, strict).pdfConfig;
  104. }
  105. public String getMimeType() {
  106. return MimeConstants.MIME_PDF;
  107. }
  108. }
  109. private static final class ParserHelper {
  110. private PDFRendererConfig pdfConfig;
  111. private ParserHelper(Configuration cfg, FOUserAgent userAgent, boolean strict) throws FOPException {
  112. pdfConfig = new PDFRendererConfig(new DefaultFontConfigParser().parse(cfg, strict));
  113. if (cfg != null) {
  114. configure(cfg, userAgent, strict);
  115. }
  116. }
  117. private void put(PDFRendererConfigOption option, Object value) {
  118. if (value != null && !value.equals(option.getDefaultValue())) {
  119. pdfConfig.configOptions.put(option, value);
  120. }
  121. }
  122. private void configure(Configuration cfg, FOUserAgent userAgent, boolean strict)
  123. throws FOPException {
  124. try {
  125. buildFilterMapFromConfiguration(cfg);
  126. put(PDF_A_MODE, PDFAMode.getValueOf(parseConfig(cfg, PDF_A_MODE)));
  127. put(PDF_X_MODE, PDFXMode.getValueOf(parseConfig(cfg, PDF_X_MODE)));
  128. Configuration encryptCfg = cfg.getChild(ENCRYPTION_PARAMS.getName(), false);
  129. if (encryptCfg != null) {
  130. PDFEncryptionParams encryptionConfig = new PDFEncryptionParams();
  131. encryptionConfig.setOwnerPassword(parseConfig(encryptCfg, OWNER_PASSWORD));
  132. encryptionConfig.setUserPassword(parseConfig(encryptCfg, USER_PASSWORD));
  133. encryptionConfig.setAllowPrint(!doesValueExist(encryptCfg, NO_PRINT));
  134. encryptionConfig.setAllowCopyContent(!doesValueExist(encryptCfg, NO_COPY_CONTENT));
  135. encryptionConfig.setAllowEditContent(!doesValueExist(encryptCfg, NO_EDIT_CONTENT));
  136. encryptionConfig.setAllowEditAnnotations(!doesValueExist(encryptCfg, NO_ANNOTATIONS));
  137. encryptionConfig.setAllowFillInForms(!doesValueExist(encryptCfg, NO_FILLINFORMS));
  138. encryptionConfig.setAllowAccessContent(!doesValueExist(encryptCfg, NO_ACCESSCONTENT));
  139. encryptionConfig.setAllowAssembleDocument(!doesValueExist(encryptCfg,
  140. NO_ASSEMBLEDOC));
  141. encryptionConfig.setAllowPrintHq(!doesValueExist(encryptCfg, NO_PRINTHQ));
  142. String encryptionLength = parseConfig(encryptCfg, ENCRYPTION_LENGTH);
  143. if (encryptionLength != null) {
  144. int validatedLength = checkEncryptionLength(Integer.parseInt(encryptionLength),
  145. userAgent);
  146. encryptionConfig.setEncryptionLengthInBits(validatedLength);
  147. }
  148. put(ENCRYPTION_PARAMS, encryptionConfig);
  149. }
  150. put(OUTPUT_PROFILE, InternalResourceResolver.cleanURI(parseConfig(cfg, OUTPUT_PROFILE)));
  151. put(DISABLE_SRGB_COLORSPACE, Boolean.valueOf(parseConfig(cfg, DISABLE_SRGB_COLORSPACE)));
  152. put(VERSION, getPDFDocVersion(cfg));
  153. } catch (ConfigurationException e) {
  154. LogUtil.handleException(LOG, e, strict);
  155. } catch (URISyntaxException use) {
  156. LogUtil.handleException(LOG, use, strict);
  157. }
  158. }
  159. private void buildFilterMapFromConfiguration(Configuration cfg)
  160. throws ConfigurationException, FOPException {
  161. Configuration[] filterLists = cfg.getChildren(FILTER_LIST.getName());
  162. Map<String, List<String>> filterMap = new HashMap<String, List<String>>();
  163. for (Configuration filters : filterLists) {
  164. String type = filters.getAttribute("type", PDFFilterList.DEFAULT_FILTER);
  165. List<String> filterList = new ArrayList<String>();
  166. for (Configuration nameCfg : filters.getChildren("value")) {
  167. filterList.add(nameCfg.getValue());
  168. }
  169. if (!filterList.isEmpty() && LOG.isDebugEnabled()) {
  170. StringBuffer debug = new StringBuffer("Adding PDF filter");
  171. if (filterList.size() != 1) {
  172. debug.append("s");
  173. }
  174. debug.append(" for type ").append(type).append(": ");
  175. for (int j = 0; j < filterList.size(); j++) {
  176. if (j != 0) {
  177. debug.append(", ");
  178. }
  179. debug.append(filterList.get(j));
  180. }
  181. LogUtil.handleError(LOG, debug.toString(), true);
  182. }
  183. if (filterMap.get(type) != null) {
  184. throw new ConfigurationException("A filterList of type '"
  185. + type + "' has already been defined");
  186. }
  187. filterMap.put(type, filterList);
  188. }
  189. put(FILTER_LIST, filterMap);
  190. }
  191. private String parseConfig(Configuration cfg, PDFRendererConfigOption option) {
  192. Configuration child = cfg.getChild(option.getName());
  193. return child.getValue(null);
  194. }
  195. private boolean doesValueExist(Configuration cfg, PDFRendererConfigOption option) {
  196. return cfg.getChild(option.getName(), false) != null;
  197. }
  198. private String getPDFDocVersion(Configuration cfg) throws FOPException {
  199. Configuration pdfVersion = cfg.getChild(VERSION.getName(), false);
  200. if (pdfVersion != null) {
  201. String version = pdfVersion.getValue(null);
  202. if (version != null && version.length() != 0) {
  203. return version;
  204. } else {
  205. throw new FOPException("The PDF version has not been set.");
  206. }
  207. }
  208. return null;
  209. }
  210. private int checkEncryptionLength(int encryptionLength, FOUserAgent userAgent) {
  211. int correctEncryptionLength = encryptionLength;
  212. if (encryptionLength < 40) {
  213. correctEncryptionLength = 40;
  214. } else if (encryptionLength > 128) {
  215. correctEncryptionLength = 128;
  216. } else if (encryptionLength % 8 != 0) {
  217. correctEncryptionLength = Math.round(encryptionLength / 8.0f) * 8;
  218. }
  219. if (correctEncryptionLength != encryptionLength && userAgent != null) {
  220. PDFEventProducer.Provider.get(userAgent.getEventBroadcaster())
  221. .incorrectEncryptionLength(this, encryptionLength,
  222. correctEncryptionLength);
  223. }
  224. return correctEncryptionLength;
  225. }
  226. }
  227. }