Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

PDFRendererConfig.java 14KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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.util.ArrayList;
  20. import java.util.EnumMap;
  21. import java.util.HashMap;
  22. import java.util.List;
  23. import java.util.Map;
  24. import org.apache.commons.logging.Log;
  25. import org.apache.commons.logging.LogFactory;
  26. import org.apache.fop.apps.FOPException;
  27. import org.apache.fop.apps.FOUserAgent;
  28. import org.apache.fop.apps.MimeConstants;
  29. import org.apache.fop.configuration.Configuration;
  30. import org.apache.fop.configuration.ConfigurationException;
  31. import org.apache.fop.fonts.DefaultFontConfig;
  32. import org.apache.fop.fonts.DefaultFontConfig.DefaultFontConfigParser;
  33. import org.apache.fop.fonts.FontEventAdapter;
  34. import org.apache.fop.pdf.PDFEncryptionParams;
  35. import org.apache.fop.pdf.PDFFilterList;
  36. import org.apache.fop.pdf.PDFSignParams;
  37. import org.apache.fop.render.RendererConfig;
  38. import org.apache.fop.render.RendererConfigOption;
  39. import org.apache.fop.util.LogUtil;
  40. import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_LENGTH;
  41. import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPTION_PARAMS;
  42. import static org.apache.fop.render.pdf.PDFEncryptionOption.ENCRYPT_METADATA;
  43. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ACCESSCONTENT;
  44. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ANNOTATIONS;
  45. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_ASSEMBLEDOC;
  46. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_COPY_CONTENT;
  47. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_EDIT_CONTENT;
  48. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_FILLINFORMS;
  49. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_PRINT;
  50. import static org.apache.fop.render.pdf.PDFEncryptionOption.NO_PRINTHQ;
  51. import static org.apache.fop.render.pdf.PDFEncryptionOption.OWNER_PASSWORD;
  52. import static org.apache.fop.render.pdf.PDFEncryptionOption.USER_PASSWORD;
  53. import static org.apache.fop.render.pdf.PDFRendererOption.DISABLE_SRGB_COLORSPACE;
  54. import static org.apache.fop.render.pdf.PDFRendererOption.FILTER_LIST;
  55. import static org.apache.fop.render.pdf.PDFRendererOption.FORM_XOBJECT;
  56. import static org.apache.fop.render.pdf.PDFRendererOption.LINEARIZATION;
  57. import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FONTS;
  58. import static org.apache.fop.render.pdf.PDFRendererOption.MERGE_FORM_FIELDS;
  59. import static org.apache.fop.render.pdf.PDFRendererOption.OUTPUT_PROFILE;
  60. import static org.apache.fop.render.pdf.PDFRendererOption.PDF_A_MODE;
  61. import static org.apache.fop.render.pdf.PDFRendererOption.PDF_UA_MODE;
  62. import static org.apache.fop.render.pdf.PDFRendererOption.PDF_VT_MODE;
  63. import static org.apache.fop.render.pdf.PDFRendererOption.PDF_X_MODE;
  64. import static org.apache.fop.render.pdf.PDFRendererOption.VERSION;
  65. /**
  66. * The PDF renderer configuration data object.
  67. */
  68. public final class PDFRendererConfig implements RendererConfig {
  69. private static final Log LOG = LogFactory.getLog(PDFRendererConfig.class);
  70. private final PDFRendererOptionsConfig configOption;
  71. private final DefaultFontConfig fontConfig;
  72. private PDFRendererConfig(DefaultFontConfig fontConfig, PDFRendererOptionsConfig config) {
  73. this.fontConfig = fontConfig;
  74. this.configOption = config;
  75. }
  76. public PDFRendererOptionsConfig getConfigOptions() {
  77. return configOption;
  78. }
  79. public DefaultFontConfig getFontInfoConfig() {
  80. return fontConfig;
  81. }
  82. /**
  83. * The PDF renderer configuration data parser.
  84. */
  85. public static final class PDFRendererConfigParser implements RendererConfigParser {
  86. public PDFRendererConfig build(FOUserAgent userAgent, Configuration cfg) throws FOPException {
  87. boolean strict = userAgent != null ? userAgent.validateUserConfigStrictly() : false;
  88. return new ParserHelper(cfg, userAgent, strict).pdfConfig;
  89. }
  90. public String getMimeType() {
  91. return MimeConstants.MIME_PDF;
  92. }
  93. }
  94. private static final class ParserHelper {
  95. private final Map<PDFRendererOption, Object> configOptions
  96. = new EnumMap<PDFRendererOption, Object>(PDFRendererOption.class);
  97. private PDFEncryptionParams encryptionConfig;
  98. private PDFRendererConfig pdfConfig;
  99. private ParserHelper(Configuration cfg, FOUserAgent userAgent, boolean strict) throws FOPException {
  100. if (cfg != null) {
  101. configure(cfg, userAgent, strict);
  102. }
  103. if (userAgent == null) {
  104. pdfConfig = new PDFRendererConfig(new DefaultFontConfigParser().parse(cfg, strict),
  105. new PDFRendererOptionsConfig(configOptions, encryptionConfig));
  106. } else {
  107. pdfConfig = new PDFRendererConfig(new DefaultFontConfigParser().parse(cfg, strict,
  108. new FontEventAdapter(userAgent.getEventBroadcaster())),
  109. new PDFRendererOptionsConfig(configOptions, encryptionConfig));
  110. }
  111. }
  112. private void parseAndPut(PDFRendererOption option, Configuration cfg) {
  113. put(option, option.parse(parseConfig(cfg, option)));
  114. }
  115. private void put(PDFRendererOption option, Object value) {
  116. if (value != null && !value.equals(option.getDefaultValue())) {
  117. configOptions.put(option, value);
  118. }
  119. }
  120. private void configure(Configuration cfg, FOUserAgent userAgent, boolean strict) throws FOPException {
  121. try {
  122. buildFilterMapFromConfiguration(cfg);
  123. parseAndPut(PDF_A_MODE, cfg);
  124. parseAndPut(PDF_UA_MODE, cfg);
  125. parseAndPut(PDF_X_MODE, cfg);
  126. parseAndPut(PDF_VT_MODE, cfg);
  127. configureEncryptionParams(cfg, userAgent, strict);
  128. parseAndPut(OUTPUT_PROFILE, cfg);
  129. parseAndPut(DISABLE_SRGB_COLORSPACE, cfg);
  130. parseAndPut(MERGE_FONTS, cfg);
  131. parseAndPut(MERGE_FORM_FIELDS, cfg);
  132. parseAndPut(LINEARIZATION, cfg);
  133. parseAndPut(FORM_XOBJECT, cfg);
  134. parseAndPut(VERSION, cfg);
  135. configureSignParams(cfg);
  136. } catch (ConfigurationException e) {
  137. LogUtil.handleException(LOG, e, strict);
  138. }
  139. }
  140. private void configureSignParams(Configuration cfg) throws FOPException {
  141. Configuration signCfd = cfg.getChild(PDFSignOption.SIGN_PARAMS, false);
  142. if (signCfd != null) {
  143. String keystore = parseConfig(signCfd, PDFSignOption.KEYSTORE);
  144. if (keystore == null) {
  145. throw new FOPException("No keystore file defined inside sign-params");
  146. }
  147. String name = parseConfig(signCfd, PDFSignOption.NAME);
  148. String location = parseConfig(signCfd, PDFSignOption.LOCATION);
  149. String reason = parseConfig(signCfd, PDFSignOption.REASON);
  150. String password = parseConfig(signCfd, PDFSignOption.PASSWORD);
  151. PDFSignParams signParams = new PDFSignParams(keystore, name, location, reason, password);
  152. configOptions.put(PDFRendererOption.SIGN_PARAMS, signParams);
  153. }
  154. }
  155. private void configureEncryptionParams(Configuration cfg, FOUserAgent userAgent, boolean strict) {
  156. Configuration encryptCfg = cfg.getChild(ENCRYPTION_PARAMS, false);
  157. if (encryptCfg != null) {
  158. encryptionConfig = PDFRenderingUtil.createFromUserAgent(userAgent).getEncryptionParameters();
  159. if (encryptionConfig == null) {
  160. encryptionConfig = new PDFEncryptionParams();
  161. }
  162. String ownerPassword = parseConfig(encryptCfg, OWNER_PASSWORD);
  163. if (doesValueExist(encryptCfg, OWNER_PASSWORD)) {
  164. encryptionConfig.setOwnerPassword(ownerPassword);
  165. }
  166. String userPassword = parseConfig(encryptCfg, USER_PASSWORD);
  167. if (doesValueExist(encryptCfg, USER_PASSWORD)) {
  168. encryptionConfig.setUserPassword(userPassword);
  169. }
  170. if (doesValueExist(encryptCfg, NO_PRINT)) {
  171. encryptionConfig.setAllowPrint(false);
  172. }
  173. if (doesValueExist(encryptCfg, NO_COPY_CONTENT)) {
  174. encryptionConfig.setAllowCopyContent(false);
  175. }
  176. if (doesValueExist(encryptCfg, NO_EDIT_CONTENT)) {
  177. encryptionConfig.setAllowEditContent(false);
  178. }
  179. if (doesValueExist(encryptCfg, NO_ANNOTATIONS)) {
  180. encryptionConfig.setAllowEditAnnotations(false);
  181. }
  182. if (doesValueExist(encryptCfg, NO_FILLINFORMS)) {
  183. encryptionConfig.setAllowFillInForms(false);
  184. }
  185. if (doesValueExist(encryptCfg, NO_ACCESSCONTENT)) {
  186. encryptionConfig.setAllowAccessContent(false);
  187. }
  188. if (doesValueExist(encryptCfg, NO_ASSEMBLEDOC)) {
  189. encryptionConfig.setAllowAssembleDocument(false);
  190. }
  191. if (doesValueExist(encryptCfg, NO_PRINTHQ)) {
  192. encryptionConfig.setAllowPrintHq(false);
  193. }
  194. String encryptMetadata = parseConfig(encryptCfg, ENCRYPT_METADATA);
  195. if (doesValueExist(encryptCfg, ENCRYPT_METADATA)) {
  196. encryptionConfig.setEncryptMetadata(Boolean.parseBoolean(encryptMetadata));
  197. }
  198. String encryptionLength = parseConfig(encryptCfg, ENCRYPTION_LENGTH);
  199. if (doesValueExist(encryptCfg, ENCRYPTION_LENGTH)) {
  200. int validatedLength = checkEncryptionLength(Integer.parseInt(encryptionLength), userAgent);
  201. encryptionConfig.setEncryptionLengthInBits(validatedLength);
  202. }
  203. }
  204. }
  205. private void buildFilterMapFromConfiguration(Configuration cfg) throws ConfigurationException,
  206. FOPException {
  207. Configuration[] filterLists = cfg.getChildren(FILTER_LIST.getName());
  208. Map<String, List<String>> filterMap = new HashMap<String, List<String>>();
  209. for (Configuration filters : filterLists) {
  210. String type = filters.getAttribute("type", PDFFilterList.DEFAULT_FILTER);
  211. List<String> filterList = new ArrayList<String>();
  212. for (Configuration nameCfg : filters.getChildren("value")) {
  213. filterList.add(nameCfg.getValue());
  214. }
  215. if (!filterList.isEmpty() && LOG.isDebugEnabled()) {
  216. StringBuffer debug = new StringBuffer("Adding PDF filter");
  217. if (filterList.size() != 1) {
  218. debug.append("s");
  219. }
  220. debug.append(" for type ").append(type).append(": ");
  221. for (int j = 0; j < filterList.size(); j++) {
  222. if (j != 0) {
  223. debug.append(", ");
  224. }
  225. debug.append(filterList.get(j));
  226. }
  227. LOG.debug(debug.toString());
  228. }
  229. if (filterMap.get(type) != null) {
  230. throw new ConfigurationException("A filterList of type '"
  231. + type + "' has already been defined");
  232. }
  233. filterMap.put(type, filterList);
  234. }
  235. put(FILTER_LIST, filterMap);
  236. }
  237. private String parseConfig(Configuration cfg, RendererConfigOption option) {
  238. Configuration child = cfg.getChild(option.getName());
  239. String value = child.getValue(null);
  240. if (value == null || "".equals(value)) {
  241. Object v = option.getDefaultValue();
  242. return v == null ? null : v.toString();
  243. }
  244. return value;
  245. }
  246. private boolean doesValueExist(Configuration cfg, RendererConfigOption option) {
  247. return cfg.getChild(option.getName(), false) != null;
  248. }
  249. private int checkEncryptionLength(int encryptionLength, FOUserAgent userAgent) {
  250. int correctEncryptionLength = encryptionLength;
  251. if (encryptionLength < 40) {
  252. correctEncryptionLength = 40;
  253. } else if (encryptionLength > 256) {
  254. correctEncryptionLength = 256;
  255. } else if (encryptionLength > 128 && encryptionLength < 256) {
  256. correctEncryptionLength = 128;
  257. } else if (encryptionLength % 8 != 0) {
  258. correctEncryptionLength = Math.round(encryptionLength / 8.0f) * 8;
  259. }
  260. if (correctEncryptionLength != encryptionLength && userAgent != null) {
  261. PDFEventProducer.Provider.get(userAgent.getEventBroadcaster())
  262. .incorrectEncryptionLength(this, encryptionLength,
  263. correctEncryptionLength);
  264. }
  265. return correctEncryptionLength;
  266. }
  267. }
  268. }