Guest User

PDFToolkitServiceImpl.java

a guest
Dec 9th, 2016
22
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 69.03 KB | None | 0 0
  1. package org.alfresco.extension.pdftoolkit.service;
  2.  
  3. import java.io.File;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.io.Serializable;
  8. import java.io.StringWriter;
  9. import java.nio.charset.Charset;
  10. import java.security.KeyStore;
  11. import java.security.KeyStoreException;
  12. import java.security.NoSuchAlgorithmException;
  13. import java.security.PrivateKey;
  14. import java.security.UnrecoverableKeyException;
  15. import java.security.cert.Certificate;
  16. import java.security.cert.CertificateException;
  17. import java.util.ArrayList;
  18. import java.util.Date;
  19. import java.util.HashMap;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.StringTokenizer;
  24. import java.util.Vector;
  25.  
  26. import javax.imageio.ImageIO;
  27.  
  28. import org.alfresco.error.AlfrescoRuntimeException;
  29. import org.alfresco.extension.pdftoolkit.constants.PDFToolkitConstants;
  30. import org.alfresco.extension.pdftoolkit.model.PDFToolkitModel;
  31. import org.alfresco.model.ContentModel;
  32. import org.alfresco.repo.security.authentication.AuthenticationUtil;
  33. import org.alfresco.repo.template.FreeMarkerProcessor;
  34. import org.alfresco.repo.template.TemplateNode;
  35. import org.alfresco.service.ServiceRegistry;
  36. import org.alfresco.service.cmr.dictionary.DictionaryService;
  37. import org.alfresco.service.cmr.model.FileExistsException;
  38. import org.alfresco.service.cmr.model.FileFolderService;
  39. import org.alfresco.service.cmr.model.FileInfo;
  40. import org.alfresco.service.cmr.model.FileNotFoundException;
  41. import org.alfresco.service.cmr.repository.ContentIOException;
  42. import org.alfresco.service.cmr.repository.ContentReader;
  43. import org.alfresco.service.cmr.repository.ContentService;
  44. import org.alfresco.service.cmr.repository.ContentWriter;
  45. import org.alfresco.service.cmr.repository.NodeRef;
  46. import org.alfresco.service.cmr.repository.NodeService;
  47. import org.alfresco.service.cmr.security.AuthenticationService;
  48. import org.alfresco.service.cmr.security.PersonService;
  49. import org.alfresco.service.namespace.QName;
  50. import org.alfresco.util.TempFileProvider;
  51. import org.apache.commons.logging.Log;
  52. import org.apache.commons.logging.LogFactory;
  53. import org.apache.pdfbox.exceptions.COSVisitorException;
  54. import org.apache.pdfbox.pdmodel.PDDocument;
  55. import org.apache.pdfbox.util.PDFMergerUtility;
  56. import org.apache.pdfbox.util.Splitter;
  57.  
  58. import com.itextpdf.text.Document;
  59. import com.itextpdf.text.DocumentException;
  60. import com.itextpdf.text.Image;
  61. import com.itextpdf.text.Rectangle;
  62. import com.itextpdf.text.pdf.BaseFont;
  63. import com.itextpdf.text.pdf.PdfContentByte;
  64. import com.itextpdf.text.pdf.PdfCopy;
  65. import com.itextpdf.text.pdf.PdfDictionary;
  66. import com.itextpdf.text.pdf.PdfName;
  67. import com.itextpdf.text.pdf.PdfNumber;
  68. import com.itextpdf.text.pdf.PdfReader;
  69. import com.itextpdf.text.pdf.PdfSignatureAppearance;
  70. import com.itextpdf.text.pdf.PdfStamper;
  71. import com.itextpdf.text.pdf.PdfWriter;
  72. import org.alfresco.service.cmr.version.Version;
  73. import org.alfresco.repo.version.VersionModel;
  74. import org.alfresco.service.cmr.version.VersionType;
  75. import org.alfresco.service.cmr.coci.CheckOutCheckInService;
  76.  
  77. public class PDFToolkitServiceImpl extends PDFToolkitConstants implements PDFToolkitService
  78. {
  79.  
  80. private ServiceRegistry serviceRegistry;
  81. private NodeService ns;
  82. private ContentService cs;
  83. private FileFolderService ffs;
  84. private DictionaryService ds;
  85. private PersonService ps;
  86. private AuthenticationService as;
  87.  
  88. private FreeMarkerProcessor freemarkerProcessor = new FreeMarkerProcessor();
  89.  
  90. private static Log logger = LogFactory.getLog(PDFToolkitServiceImpl.class);
  91.  
  92. // do we need to apply the encryption aspect when we encrypt?
  93. private boolean useEncryptionAspect = true;
  94.  
  95. // do we need to apply the signature aspect when we sign?
  96. private boolean useSignatureAspect = true;
  97.  
  98. // when we create a new document, do we actually create a new one, or copy the source?
  99. private boolean createNew = false;
  100.  
  101. protected CheckOutCheckInService checkOutCheckInService;
  102.  
  103. Map<String, Serializable> versionProperties = new HashMap<String, Serializable>();
  104.  
  105. @Override
  106. public NodeRef appendPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  107. {
  108. PDDocument pdf = null;
  109. PDDocument pdfTarget = null;
  110. InputStream is = null;
  111. InputStream tis = null;
  112. File tempDir = null;
  113. ContentWriter writer = null;
  114. NodeRef destinationNode = null;
  115.  
  116. try
  117. {
  118. NodeRef toAppend = (NodeRef)params.get(PARAM_TARGET_NODE);
  119. Boolean inplace = true;
  120. ContentReader append = getReader(toAppend);
  121. is = append.getContentInputStream();
  122.  
  123. ContentReader targetReader = getReader(targetNodeRef);
  124. tis = targetReader.getContentInputStream();
  125.  
  126. String fileName = getFilename(params, targetNodeRef);
  127.  
  128. // stream the document in
  129. pdf = PDDocument.load(is);
  130. pdfTarget = PDDocument.load(tis);
  131.  
  132. // Append the PDFs
  133. PDFMergerUtility merger = new PDFMergerUtility();
  134. merger.appendDocument(pdfTarget, pdf);
  135. merger.setDestinationFileName(fileName);
  136. merger.mergeDocuments();
  137.  
  138. // build a temp dir name based on the ID of the noderef we are
  139. // importing
  140. File alfTempDir = TempFileProvider.getTempDir();
  141. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  142. tempDir.mkdir();
  143.  
  144. pdfTarget.save(tempDir + "" + File.separatorChar + fileName);
  145.  
  146. for (File file : tempDir.listFiles())
  147. {
  148. try
  149. {
  150. if (file.isFile())
  151. {
  152. // Get a writer and prep it for putting it back into the repo
  153. destinationNode = createDestinationNode(fileName,
  154. (NodeRef)params.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  155. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  156.  
  157. writer.setEncoding(targetReader.getEncoding()); // original
  158. // encoding
  159. writer.setMimetype(FILE_MIMETYPE);
  160.  
  161. // Put it in the repo
  162. writer.putContent(file);
  163.  
  164. // Clean up
  165. file.delete();
  166. }
  167. }
  168. catch (FileExistsException e)
  169. {
  170. throw new AlfrescoRuntimeException("Failed to process file.", e);
  171. }
  172. }
  173. }
  174. catch (COSVisitorException e)
  175. {
  176. throw new AlfrescoRuntimeException(e.getMessage(), e);
  177. }
  178. catch (IOException e)
  179. {
  180. throw new AlfrescoRuntimeException(e.getMessage(), e);
  181. }
  182.  
  183. finally
  184. {
  185. if (pdf != null)
  186. {
  187. try
  188. {
  189. pdf.close();
  190. }
  191. catch (IOException e)
  192. {
  193. throw new AlfrescoRuntimeException(e.getMessage(), e);
  194. }
  195. }
  196. if (pdfTarget != null)
  197. {
  198. try
  199. {
  200. pdfTarget.close();
  201. }
  202. catch (IOException e)
  203. {
  204. throw new AlfrescoRuntimeException(e.getMessage(), e);
  205. }
  206. }
  207. if (is != null)
  208. {
  209. try
  210. {
  211. is.close();
  212. }
  213. catch (IOException e)
  214. {
  215. throw new AlfrescoRuntimeException(e.getMessage(), e);
  216. }
  217. }
  218.  
  219. if (tempDir != null)
  220. {
  221. tempDir.delete();
  222. }
  223. }
  224.  
  225. return destinationNode;
  226. }
  227.  
  228. @Override
  229. public NodeRef encryptPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  230. {
  231. PdfStamper stamp = null;
  232. File tempDir = null;
  233. ContentWriter writer = null;
  234. ContentReader targetReader = null;
  235. NodeRef destinationNode = null;
  236.  
  237. try
  238. {
  239. // get the parameters
  240. String userPassword = (String)params.get(PARAM_USER_PASSWORD);
  241. String ownerPassword = (String)params.get(PARAM_OWNER_PASSWORD);
  242. Boolean inplace = true;
  243. //int permissions = buildPermissionMask(params);
  244. int permissions = 0;
  245. int encryptionType = Integer.parseInt((String)params.get(PARAM_ENCRYPTION_LEVEL));
  246.  
  247. // if metadata is excluded, alter encryption type
  248. /*if ((Boolean)params.get(PARAM_EXCLUDE_METADATA))
  249. {
  250. encryptionType = encryptionType | PdfWriter.DO_NOT_ENCRYPT_METADATA;
  251. }*/
  252.  
  253. // get temp file
  254. File alfTempDir = TempFileProvider.getTempDir();
  255. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  256. tempDir.mkdir();
  257. File file = new File(tempDir, ffs.getFileInfo(targetNodeRef).getName());
  258.  
  259. // get the PDF input stream and create a reader for iText
  260. targetReader = getReader(targetNodeRef);
  261. PdfReader reader = new PdfReader(targetReader.getContentInputStream());
  262. stamp = new PdfStamper(reader, new FileOutputStream(file));
  263.  
  264. // encrypt PDF
  265. stamp.setEncryption(userPassword.getBytes(Charset.forName("UTF-8")), ownerPassword.getBytes(Charset.forName("UTF-8")), permissions, encryptionType);
  266. stamp.close();
  267.  
  268. String fileName = getFilename(params, targetNodeRef);
  269.  
  270. // write out to destination
  271. destinationNode = createDestinationNode(fileName,
  272. (NodeRef)params.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  273. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  274.  
  275. writer.setEncoding(targetReader.getEncoding());
  276. writer.setMimetype(FILE_MIMETYPE);
  277. writer.putContent(file);
  278. file.delete();
  279.  
  280. //if useAspect is true, store some additional info about the signature in the props
  281. if(useEncryptionAspect)
  282. {
  283. ns.addAspect(destinationNode, PDFToolkitModel.ASPECT_ENCRYPTED, new HashMap<QName, Serializable>());
  284. ns.setProperty(destinationNode, PDFToolkitModel.PROP_ENCRYPTIONDATE, new java.util.Date());
  285. ns.setProperty(destinationNode, PDFToolkitModel.PROP_ENCRYPTEDBY, AuthenticationUtil.getRunAsUser());
  286. }
  287. versionProperties.put(VersionModel.PROP_VERSION_TYPE, VersionType.MAJOR);
  288. versionProperties.put(Version.PROP_DESCRIPTION, "Document encrypted done.");
  289. NodeRef workingNode = checkOutCheckInService.checkout(destinationNode);
  290. checkOutCheckInService.checkin(workingNode, versionProperties);
  291.  
  292. }
  293. catch (IOException e)
  294. {
  295. throw new AlfrescoRuntimeException(e.getMessage(), e);
  296. }
  297. catch (DocumentException e)
  298. {
  299. throw new AlfrescoRuntimeException(e.getMessage(), e);
  300. }
  301. finally
  302. {
  303. if (tempDir != null)
  304. {
  305. try
  306. {
  307. tempDir.delete();
  308. }
  309. catch (Exception ex)
  310. {
  311. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  312. }
  313. }
  314.  
  315. if (stamp != null)
  316. {
  317. try
  318. {
  319. stamp.close();
  320. }
  321. catch (Exception ex)
  322. {
  323. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  324. }
  325. }
  326. }
  327. return destinationNode;
  328. }
  329.  
  330. @Override
  331. public NodeRef decryptPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  332. {
  333. PdfStamper stamp = null;
  334. File tempDir = null;
  335. ContentWriter writer = null;
  336. ContentReader targetReader = null;
  337. NodeRef destinationNode = null;
  338.  
  339. try
  340. {
  341. // get the parameters
  342. String ownerPassword = (String)params.get(PARAM_OWNER_PASSWORD);
  343. Boolean inplace = true;
  344.  
  345. // get temp file
  346. File alfTempDir = TempFileProvider.getTempDir();
  347. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  348. tempDir.mkdir();
  349. File file = new File(tempDir, ffs.getFileInfo(targetNodeRef).getName());
  350.  
  351. // get the PDF input stream and create a reader for iText
  352. targetReader = getReader(targetNodeRef);
  353. PdfReader reader = new PdfReader(targetReader.getContentInputStream(), ownerPassword.getBytes());
  354. stamp = new PdfStamper(reader, new FileOutputStream(file));
  355. stamp.close();
  356.  
  357. String fileName = getFilename(params, targetNodeRef);
  358.  
  359. // write out to destination
  360. destinationNode = createDestinationNode(fileName,
  361. (NodeRef)params.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  362. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  363.  
  364. writer.setEncoding(targetReader.getEncoding());
  365. writer.setMimetype(FILE_MIMETYPE);
  366. writer.putContent(file);
  367. file.delete();
  368.  
  369. //if useAspect is true, store some additional info about the signature in the props
  370. if(useEncryptionAspect)
  371. {
  372. ns.removeAspect(destinationNode, PDFToolkitModel.ASPECT_ENCRYPTED);
  373. }
  374. }
  375. catch (IOException e)
  376. {
  377. throw new AlfrescoRuntimeException(e.getMessage(), e);
  378. }
  379. catch (DocumentException e)
  380. {
  381. throw new AlfrescoRuntimeException(e.getMessage(), e);
  382. }
  383. finally
  384. {
  385. if (tempDir != null)
  386. {
  387. try
  388. {
  389. tempDir.delete();
  390. }
  391. catch (Exception ex)
  392. {
  393. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  394. }
  395. }
  396.  
  397. if (stamp != null)
  398. {
  399. try
  400. {
  401. stamp.close();
  402. }
  403. catch (Exception ex)
  404. {
  405. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  406. }
  407. }
  408. }
  409.  
  410. return destinationNode;
  411. }
  412.  
  413. @Override
  414. public NodeRef signPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  415. {
  416. NodeRef privateKey = (NodeRef)params.get(PARAM_PRIVATE_KEY);
  417. String location = (String)params.get(PARAM_LOCATION);
  418. String position = (String)params.get(PARAM_POSITION);
  419. String reason = (String)params.get(PARAM_REASON);
  420. String visibility = (String)params.get(PARAM_VISIBILITY);
  421. String keyPassword = (String)params.get(PARAM_KEY_PASSWORD);
  422. String keyType = (String)params.get(PARAM_KEY_TYPE);
  423. int height = getInteger(params.get(PARAM_HEIGHT));
  424. int width = getInteger(params.get(PARAM_WIDTH));
  425. int pageNumber = getInteger(params.get(PARAM_PAGE));
  426.  
  427. // By default, append the signature as a new PDF revision to avoid
  428. // invalidating any signatures that might already exist on the doc
  429. boolean appendToExisting = true;
  430. if (params.get(PARAM_NEW_REVISION) != null) {
  431. appendToExisting = Boolean.valueOf(String.valueOf(params.get(PARAM_NEW_REVISION)));
  432. }
  433.  
  434. // New keystore parameters
  435. String alias = (String)params.get(PARAM_ALIAS);
  436. String storePassword = (String)params.get(PARAM_STORE_PASSWORD);
  437.  
  438. int locationX = getInteger(params.get(PARAM_LOCATION_X));
  439. int locationY = getInteger(params.get(PARAM_LOCATION_Y));
  440.  
  441. Boolean inplace = true;
  442.  
  443. File tempDir = null;
  444. ContentWriter writer = null;
  445. KeyStore ks = null;
  446.  
  447. NodeRef destinationNode = null;
  448.  
  449. try
  450. {
  451. // get a keystore instance by
  452. if (keyType == null || keyType.equalsIgnoreCase(KEY_TYPE_DEFAULT))
  453. {
  454. ks = KeyStore.getInstance(KeyStore.getDefaultType());
  455. }
  456. else if (keyType.equalsIgnoreCase(KEY_TYPE_PKCS12))
  457. {
  458. ks = KeyStore.getInstance("pkcs12");
  459. }
  460. else
  461. {
  462. throw new AlfrescoRuntimeException("Unknown key type " + keyType + " specified");
  463. }
  464.  
  465. // open the reader to the key and load it
  466. ContentReader keyReader = getReader(privateKey);
  467. ks.load(keyReader.getContentInputStream(), storePassword.toCharArray());
  468.  
  469. // set alias
  470. // String alias = (String) ks.aliases().nextElement();
  471.  
  472. PrivateKey key = (PrivateKey)ks.getKey(alias, keyPassword.toCharArray());
  473. Certificate[] chain = ks.getCertificateChain(alias);
  474.  
  475. // open original pdf
  476. ContentReader pdfReader = getReader(targetNodeRef);
  477. PdfReader reader = new PdfReader(pdfReader.getContentInputStream());
  478.  
  479. // If the page number is 0 because it couldn't be parsed or for
  480. // some other reason, set it to the first page, which is 1.
  481. // If the page number is negative, assume the intent is to "wrap".
  482. // For example, -1 would always be the last page.
  483. int numPages = reader.getNumberOfPages();
  484. if (pageNumber < 1 && pageNumber == 0) {
  485. pageNumber = 1; // use the first page
  486. } else {
  487. // page number is negative
  488. pageNumber = numPages + 1 + pageNumber;
  489. if (pageNumber <= 0) pageNumber = 1;
  490. }
  491.  
  492. // if the page number specified is more than the num of pages,
  493. // use the last page
  494. if (pageNumber > numPages) {
  495. pageNumber = numPages;
  496. }
  497.  
  498. // create temp dir to store file
  499. File alfTempDir = TempFileProvider.getTempDir();
  500. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  501. tempDir.mkdir();
  502. File file = new File(tempDir, ffs.getFileInfo(targetNodeRef).getName());
  503.  
  504. FileOutputStream fout = new FileOutputStream(file);
  505.  
  506. // When adding a second signature, append must be called on PdfStamper.createSignature
  507. // to avoid invalidating previous signatures
  508. PdfStamper stamp = null;
  509. if (appendToExisting) {
  510. stamp = PdfStamper.createSignature(reader, fout, '\0', tempDir, true);
  511. } else {
  512. stamp = PdfStamper.createSignature(reader, fout, '\0');
  513. }
  514. PdfSignatureAppearance sap = stamp.getSignatureAppearance();
  515. sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
  516.  
  517. // set reason for signature and location of signer
  518. sap.setReason(reason);
  519. sap.setLocation(location);
  520.  
  521. if (visibility.equalsIgnoreCase(VISIBILITY_VISIBLE))
  522. {
  523. //create the signature rectangle using either the provided position or
  524. //the exact coordinates, if provided
  525. if(position != null && !position.trim().equalsIgnoreCase("")
  526. && !position.trim().equalsIgnoreCase(POSITION_MANUAL))
  527. {
  528. Rectangle pageRect = reader.getPageSizeWithRotation(pageNumber);
  529. sap.setVisibleSignature(positionSignature(position, pageRect, width, height), pageNumber, null);
  530. }
  531. else
  532. {
  533. sap.setVisibleSignature(new Rectangle(locationX, locationY, locationX + width, locationY - height), pageNumber, null);
  534. }
  535. }
  536.  
  537. stamp.close();
  538.  
  539. String fileName = getFilename(params, targetNodeRef);
  540.  
  541. destinationNode = createDestinationNode(fileName,
  542. (NodeRef)params.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  543. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  544.  
  545. writer.setEncoding(pdfReader.getEncoding());
  546. writer.setMimetype(FILE_MIMETYPE);
  547. writer.putContent(file);
  548.  
  549. file.delete();
  550.  
  551. //if useAspect is true, store some additional info about the signature in the props
  552. if(useSignatureAspect)
  553. {
  554. ns.addAspect(destinationNode, PDFToolkitModel.ASPECT_SIGNED, new HashMap<QName, Serializable>());
  555. ns.setProperty(destinationNode, PDFToolkitModel.PROP_REASON, reason);
  556. ns.setProperty(destinationNode, PDFToolkitModel.PROP_LOCATION, location);
  557. ns.setProperty(destinationNode, PDFToolkitModel.PROP_SIGNATUREDATE, new java.util.Date());
  558. ns.setProperty(destinationNode, PDFToolkitModel.PROP_SIGNEDBY, AuthenticationUtil.getRunAsUser());
  559. }
  560.  
  561. }
  562. catch (IOException e)
  563. {
  564. throw new AlfrescoRuntimeException(e.getMessage(), e);
  565. }
  566. catch (KeyStoreException e)
  567. {
  568. throw new AlfrescoRuntimeException(e.getMessage(), e);
  569. }
  570. catch (ContentIOException e)
  571. {
  572. throw new AlfrescoRuntimeException(e.getMessage(), e);
  573. }
  574. catch (NoSuchAlgorithmException e)
  575. {
  576. throw new AlfrescoRuntimeException(e.getMessage(), e);
  577. }
  578. catch (CertificateException e)
  579. {
  580. throw new AlfrescoRuntimeException(e.getMessage(), e);
  581. }
  582. catch (UnrecoverableKeyException e)
  583. {
  584. throw new AlfrescoRuntimeException(e.getMessage(), e);
  585. }
  586. catch (DocumentException e)
  587. {
  588. throw new AlfrescoRuntimeException(e.getMessage(), e);
  589. }
  590. finally
  591. {
  592. if (tempDir != null)
  593. {
  594. try
  595. {
  596. tempDir.delete();
  597. }
  598. catch (Exception ex)
  599. {
  600. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  601. }
  602. }
  603. }
  604.  
  605. return destinationNode;
  606. }
  607.  
  608. @Override
  609. public NodeRef watermarkPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  610. {
  611.  
  612. NodeRef destinationNode = null;
  613.  
  614. try
  615. {
  616. ContentReader targetReader = getReader(targetNodeRef);
  617.  
  618. if (params.get(PARAM_WATERMARK_TYPE) != null
  619. && params.get(PARAM_WATERMARK_TYPE).equals(TYPE_IMAGE))
  620. {
  621.  
  622. NodeRef watermarkNodeRef = (NodeRef)params.get(PARAM_WATERMARK_IMAGE);
  623. ContentReader watermarkContentReader = getReader(watermarkNodeRef);
  624. destinationNode = this.imageAction(params, targetNodeRef, watermarkNodeRef, targetReader, watermarkContentReader);
  625.  
  626. }
  627. else if (params.get(PARAM_WATERMARK_TYPE) != null
  628. && params.get(PARAM_WATERMARK_TYPE).equals(TYPE_TEXT))
  629. {
  630. destinationNode = this.textAction(params, targetNodeRef, targetReader);
  631. }
  632. }
  633. catch (AlfrescoRuntimeException e)
  634. {
  635. throw new AlfrescoRuntimeException(e.getMessage(), e);
  636. }
  637.  
  638. return destinationNode;
  639. }
  640.  
  641. @Override
  642. public NodeRef splitPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  643. {
  644. PDDocument pdf = null;
  645. InputStream is = null;
  646. File tempDir = null;
  647. ContentWriter writer = null;
  648. NodeRef destinationFolder;
  649.  
  650. try
  651. {
  652. destinationFolder = (NodeRef)params.get(PARAM_DESTINATION_FOLDER);
  653.  
  654. ContentReader targetReader = getReader(targetNodeRef);
  655.  
  656. // Get the split frequency
  657. int splitFrequency = 0;
  658.  
  659. String splitFrequencyString = params.get(PARAM_SPLIT_FREQUENCY).toString();
  660. if (!splitFrequencyString.equals(""))
  661. {
  662. splitFrequency = Integer.valueOf(splitFrequencyString);
  663. }
  664.  
  665. // Get contentReader inputStream
  666. is = targetReader.getContentInputStream();
  667. // stream the document in
  668. pdf = PDDocument.load(is);
  669. // split the PDF and put the pages in a list
  670. Splitter splitter = new Splitter();
  671. // if the default split is not every page, then set it to the right
  672. // frequency
  673. if (splitFrequency > 0)
  674. {
  675. splitter.setSplitAtPage(splitFrequency);
  676. }
  677. // Split the pages
  678. List<PDDocument> pdfs = splitter.split(pdf);
  679.  
  680. // Lets get reading to walk the list
  681. Iterator<PDDocument> it = pdfs.iterator();
  682.  
  683. // Start page split numbering at
  684. int page = 1;
  685. int endPage = 0;
  686.  
  687. // build a temp dir name based on the ID of the noderef we are
  688. // importing
  689. File alfTempDir = TempFileProvider.getTempDir();
  690. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  691. tempDir.mkdir();
  692.  
  693. while (it.hasNext())
  694. {
  695. // Pulling together the right string split pages
  696. String pagePlus = "";
  697. String pg = "_pg";
  698.  
  699. // Get the split document and save it into the temp dir with new
  700. // name
  701. PDDocument splitpdf = (PDDocument)it.next();
  702.  
  703. int pagesInPDF = splitpdf.getNumberOfPages();
  704.  
  705. if (splitFrequency > 0)
  706. {
  707. endPage = endPage + pagesInPDF;
  708.  
  709. pagePlus = "-" + endPage;
  710. pg = "_pgs";
  711.  
  712. }
  713.  
  714. // put together the name and save the PDF
  715. String fileNameSansExt = getFilenameSansExt(targetNodeRef, FILE_EXTENSION);
  716. splitpdf.save(tempDir + "" + File.separatorChar + fileNameSansExt + pg + page + pagePlus + FILE_EXTENSION);
  717.  
  718. // increment page count
  719. if (splitFrequency > 0)
  720. {
  721. page = (page++) + pagesInPDF;
  722. }
  723. else
  724. {
  725. page++;
  726. }
  727.  
  728. try
  729. {
  730. splitpdf.close();
  731. }
  732. catch (IOException e)
  733. {
  734. throw new AlfrescoRuntimeException(e.getMessage(), e);
  735. }
  736.  
  737. }
  738.  
  739. for (File file : tempDir.listFiles())
  740. {
  741. try
  742. {
  743. if (file.isFile())
  744. {
  745.  
  746. // Get a writer and prep it for putting it back into the
  747. // repo
  748. NodeRef destinationNode = createDestinationNode(file.getName(),
  749. destinationFolder, targetNodeRef, false);
  750. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  751.  
  752. writer.setEncoding(targetReader.getEncoding()); // original
  753. // encoding
  754. writer.setMimetype(FILE_MIMETYPE);
  755.  
  756. // Put it in the repo
  757. writer.putContent(file);
  758.  
  759. // Clean up
  760. file.delete();
  761. }
  762. }
  763. catch (FileExistsException e)
  764. {
  765. throw new AlfrescoRuntimeException("Failed to process file.", e);
  766. }
  767. }
  768. }
  769. catch (COSVisitorException e)
  770. {
  771. throw new AlfrescoRuntimeException(e.getMessage(), e);
  772. }
  773. catch (IOException e)
  774. {
  775. throw new AlfrescoRuntimeException(e.getMessage(), e);
  776. }
  777.  
  778. finally
  779. {
  780. if (pdf != null)
  781. {
  782. try
  783. {
  784. pdf.close();
  785. }
  786. catch (IOException e)
  787. {
  788. throw new AlfrescoRuntimeException(e.getMessage(), e);
  789. }
  790. }
  791. if (is != null)
  792. {
  793. try
  794. {
  795. is.close();
  796. }
  797. catch (IOException e)
  798. {
  799. throw new AlfrescoRuntimeException(e.getMessage(), e);
  800. }
  801. }
  802.  
  803. if (tempDir != null)
  804. {
  805. tempDir.delete();
  806. }
  807. }
  808.  
  809. return destinationFolder;
  810. }
  811.  
  812. @Override
  813. public NodeRef splitPDFAtPage(NodeRef targetNodeRef, Map<String, Serializable> params)
  814. {
  815. PDDocument pdf = null;
  816. InputStream is = null;
  817. File tempDir = null;
  818. ContentWriter writer = null;
  819. NodeRef destinationFolder;
  820.  
  821. try
  822. {
  823. destinationFolder = (NodeRef)params.get(PARAM_DESTINATION_FOLDER);
  824. ContentReader targetReader = getReader(targetNodeRef);
  825.  
  826. // Get the split frequency
  827. int splitPageNumber = 0;
  828.  
  829. String splitPage = params.get(PARAM_PAGE).toString();
  830. if (!splitPage.equals(""))
  831. {
  832. try
  833. {
  834. splitPageNumber = Integer.valueOf(splitPage);
  835. }
  836. catch (NumberFormatException e)
  837. {
  838. throw new AlfrescoRuntimeException(e.getMessage(), e);
  839. }
  840. }
  841.  
  842. // Get contentReader inputStream
  843. is = targetReader.getContentInputStream();
  844. // stream the document in
  845. pdf = PDDocument.load(is);
  846. // split the PDF and put the pages in a list
  847. Splitter splitter = new Splitter();
  848. // Need to adjust the input value to get the split at the right page
  849. splitter.setSplitAtPage(splitPageNumber - 1);
  850.  
  851. // Split the pages
  852. List<PDDocument> pdfs = splitter.split(pdf);
  853.  
  854. // Start page split numbering at
  855. int page = 1;
  856.  
  857. // build a temp dir, name based on the ID of the noderef we are
  858. // importing
  859. File alfTempDir = TempFileProvider.getTempDir();
  860. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  861. tempDir.mkdir();
  862.  
  863. // FLAG: This is ugly.....get the first PDF.
  864. PDDocument firstPDF = (PDDocument)pdfs.remove(0);
  865.  
  866. int pagesInFirstPDF = firstPDF.getNumberOfPages();
  867.  
  868. String lastPage = "";
  869. String pg = "_pg";
  870.  
  871. if (pagesInFirstPDF > 1)
  872. {
  873. pg = "_pgs";
  874. lastPage = "-" + pagesInFirstPDF;
  875. }
  876.  
  877. String fileNameSansExt = getFilenameSansExt(targetNodeRef, FILE_EXTENSION);
  878. firstPDF.save(tempDir + "" + File.separatorChar + fileNameSansExt + pg + page + lastPage + FILE_EXTENSION);
  879.  
  880. try
  881. {
  882. firstPDF.close();
  883. }
  884. catch (IOException e)
  885. {
  886. throw new AlfrescoRuntimeException(e.getMessage(), e);
  887. }
  888.  
  889. // FLAG: Like I said: "_UGLY_" ..... and it gets worse
  890. PDDocument secondPDF = null;
  891.  
  892. Iterator<PDDocument> its = pdfs.iterator();
  893.  
  894. int pagesInSecondPDF = 0;
  895.  
  896. while (its.hasNext())
  897. {
  898. if (secondPDF != null)
  899. {
  900. // Get the split document and save it into the temp dir with
  901. // new name
  902. PDDocument splitpdf = (PDDocument)its.next();
  903.  
  904. int pagesInThisPDF = splitpdf.getNumberOfPages();
  905. pagesInSecondPDF = pagesInSecondPDF + pagesInThisPDF;
  906.  
  907. PDFMergerUtility merger = new PDFMergerUtility();
  908. merger.appendDocument(secondPDF, splitpdf);
  909. merger.mergeDocuments();
  910.  
  911. try
  912. {
  913. splitpdf.close();
  914. }
  915. catch (IOException e)
  916. {
  917. throw new AlfrescoRuntimeException(e.getMessage(), e);
  918. }
  919. }
  920. else
  921. {
  922. secondPDF = (PDDocument)its.next();
  923. pagesInSecondPDF = secondPDF.getNumberOfPages();
  924. }
  925. }
  926.  
  927. if (pagesInSecondPDF > 1)
  928. {
  929. pg = "_pgs";
  930. lastPage = "-" + (pagesInSecondPDF + pagesInFirstPDF);
  931. }
  932. else
  933. {
  934. pg = "_pg";
  935. lastPage = "";
  936. }
  937.  
  938. // This is where we should save the appended PDF
  939. // put together the name and save the PDF
  940. secondPDF.save(tempDir + "" + File.separatorChar + fileNameSansExt + pg + splitPageNumber + lastPage + FILE_EXTENSION);
  941.  
  942. for (File file : tempDir.listFiles())
  943. {
  944. try
  945. {
  946. if (file.isFile())
  947. {
  948. // Get a writer and prep it for putting it back into the
  949. // repo
  950. NodeRef destinationNode = createDestinationNode(file.getName(),
  951. destinationFolder, targetNodeRef, false);
  952. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  953.  
  954. writer.setEncoding(targetReader.getEncoding()); // original
  955. // encoding
  956. writer.setMimetype(FILE_MIMETYPE);
  957.  
  958. // Put it in the repo
  959. writer.putContent(file);
  960.  
  961. // Clean up
  962. file.delete();
  963. }
  964. }
  965. catch (FileExistsException e)
  966. {
  967. throw new AlfrescoRuntimeException("Failed to process file.", e);
  968. }
  969. }
  970. }
  971. catch (COSVisitorException e)
  972. {
  973. throw new AlfrescoRuntimeException(e.getMessage(), e);
  974. }
  975. catch (IOException e)
  976. {
  977. throw new AlfrescoRuntimeException(e.getMessage(), e);
  978. }
  979.  
  980. finally
  981. {
  982. if (pdf != null)
  983. {
  984. try
  985. {
  986. pdf.close();
  987. }
  988. catch (IOException e)
  989. {
  990. throw new AlfrescoRuntimeException(e.getMessage(), e);
  991. }
  992. }
  993. if (is != null)
  994. {
  995. try
  996. {
  997. is.close();
  998. }
  999. catch (IOException e)
  1000. {
  1001. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1002. }
  1003. }
  1004.  
  1005. if (tempDir != null)
  1006. {
  1007. tempDir.delete();
  1008. }
  1009. }
  1010. return destinationFolder;
  1011. }
  1012.  
  1013. @Override
  1014. public NodeRef insertPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  1015. {
  1016. PDDocument pdf = null;
  1017. PDDocument insertContentPDF = null;
  1018. InputStream is = null;
  1019. InputStream cis = null;
  1020. File tempDir = null;
  1021. ContentWriter writer = null;
  1022. NodeRef destinationNode = null;
  1023.  
  1024. try
  1025. {
  1026.  
  1027. ContentReader targetReader = getReader(targetNodeRef);
  1028. ContentReader insertReader = getReader((NodeRef)params.get(PARAM_TARGET_NODE));
  1029. int insertAt = Integer.valueOf((String)params.get(PARAM_PAGE)).intValue();
  1030. Boolean inplace = true;
  1031.  
  1032. // Get contentReader inputStream
  1033. is = targetReader.getContentInputStream();
  1034. // Get insertContentReader inputStream
  1035. cis = insertReader.getContentInputStream();
  1036. // stream the target document in
  1037. pdf = PDDocument.load(is);
  1038. // stream the insert content document in
  1039. insertContentPDF = PDDocument.load(cis);
  1040.  
  1041. // split the PDF and put the pages in a list
  1042. Splitter splitter = new Splitter();
  1043.  
  1044. // Split the pages
  1045. List<PDDocument> pdfs = splitter.split(pdf);
  1046.  
  1047. // Build the output PDF
  1048. PDFMergerUtility merger = new PDFMergerUtility();
  1049.  
  1050. PDDocument newDocument = new PDDocument();
  1051.  
  1052. for (int i = 0; i < pdfs.size(); i++) {
  1053.  
  1054. if (i == insertAt -1) {
  1055. merger.appendDocument(newDocument, insertContentPDF);
  1056. }
  1057.  
  1058. merger.appendDocument(newDocument, (PDDocument)pdfs.get(i));
  1059. }
  1060.  
  1061. merger.setDestinationFileName(params.get(PARAM_DESTINATION_NAME).toString());
  1062. merger.mergeDocuments();
  1063.  
  1064. // build a temp dir, name based on the ID of the noderef we are
  1065. // importing
  1066. File alfTempDir = TempFileProvider.getTempDir();
  1067. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  1068. tempDir.mkdir();
  1069.  
  1070. String fileName = params.get(PARAM_DESTINATION_NAME).toString();
  1071.  
  1072. PDDocument completePDF = newDocument;
  1073.  
  1074. completePDF.save(tempDir + "" + File.separatorChar + fileName + FILE_EXTENSION);
  1075.  
  1076. try
  1077. {
  1078. completePDF.close();
  1079. newDocument.close();
  1080. }
  1081. catch (IOException e)
  1082. {
  1083. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1084. }
  1085.  
  1086. for (File file : tempDir.listFiles())
  1087. {
  1088. try
  1089. {
  1090. if (file.isFile())
  1091. {
  1092.  
  1093. // Get a writer and prep it for putting it back into the
  1094. // repo
  1095. destinationNode = createDestinationNode(file.getName(),
  1096. (NodeRef)params.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  1097. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  1098.  
  1099. writer.setEncoding(targetReader.getEncoding()); // original
  1100. // encoding
  1101. writer.setMimetype(FILE_MIMETYPE);
  1102.  
  1103. // Put it in the repo
  1104. writer.putContent(file);
  1105.  
  1106. // Clean up
  1107. file.delete();
  1108. }
  1109. }
  1110. catch (FileExistsException e)
  1111. {
  1112. throw new AlfrescoRuntimeException("Failed to process file.", e);
  1113. }
  1114. }
  1115. }
  1116. // TODO add better handling
  1117. catch (COSVisitorException e)
  1118. {
  1119. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1120. }
  1121. catch (IOException e)
  1122. {
  1123. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1124. }
  1125.  
  1126. finally
  1127. {
  1128. if (pdf != null)
  1129. {
  1130. try
  1131. {
  1132. pdf.close();
  1133. }
  1134. catch (IOException e)
  1135. {
  1136. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1137. }
  1138. }
  1139. if (is != null)
  1140. {
  1141. try
  1142. {
  1143. is.close();
  1144. }
  1145. catch (IOException e)
  1146. {
  1147. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1148. }
  1149. }
  1150.  
  1151. if (tempDir != null)
  1152. {
  1153. tempDir.delete();
  1154. }
  1155. }
  1156.  
  1157. return destinationNode;
  1158. }
  1159.  
  1160. @Override
  1161. public NodeRef deletePagesFromPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  1162. {
  1163. String pages = String.valueOf(params.get(PARAM_PAGE));
  1164. return subsetPDFDocument(targetNodeRef, params, pages, true, true);
  1165. }
  1166.  
  1167. @Override
  1168. public NodeRef extractPagesFromPDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  1169. {
  1170. String pages = String.valueOf(params.get(PARAM_PAGE));
  1171. return subsetPDFDocument(targetNodeRef, params, pages, false, false);
  1172. }
  1173.  
  1174. @Override
  1175. public NodeRef rotatePDF(NodeRef targetNodeRef, Map<String, Serializable> params)
  1176. {
  1177. InputStream is = null;
  1178. File tempDir = null;
  1179. ContentWriter writer = null;
  1180. PdfReader pdfReader = null;
  1181. NodeRef destinationNode = null;
  1182.  
  1183. try
  1184. {
  1185. ContentReader targetReader = getReader(targetNodeRef);
  1186. is = targetReader.getContentInputStream();
  1187.  
  1188. File alfTempDir = TempFileProvider.getTempDir();
  1189. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  1190. tempDir.mkdir();
  1191.  
  1192. Boolean inplace = true;
  1193. Integer degrees = Integer.valueOf(String.valueOf(params.get(PARAM_DEGREES)));
  1194. String pages = String.valueOf(params.get(PARAM_PAGE));
  1195.  
  1196. if(degrees % 90 != 0)
  1197. {
  1198. throw new AlfrescoRuntimeException("Rotation degres must be a multiple of 90 (90, 180, 270, etc)");
  1199. }
  1200.  
  1201. String fileName = getFilename(params, targetNodeRef);
  1202.  
  1203. File file = new File(tempDir, ffs.getFileInfo(targetNodeRef).getName());
  1204.  
  1205. pdfReader = new PdfReader(is);
  1206. PdfStamper stamp = new PdfStamper(pdfReader, new FileOutputStream(file));
  1207.  
  1208. int rotation = 0;
  1209. PdfDictionary pageDictionary;
  1210. int numPages = pdfReader.getNumberOfPages();
  1211. for (int pageNum = 1; pageNum <= numPages; pageNum++)
  1212. {
  1213. // only apply stamp to requested pages
  1214. if (checkPage(pages, pageNum, numPages))
  1215. {
  1216. rotation = pdfReader.getPageRotation(pageNum);
  1217. pageDictionary = pdfReader.getPageN(pageNum);
  1218. pageDictionary.put(PdfName.ROTATE, new PdfNumber(rotation + degrees));
  1219. }
  1220. }
  1221.  
  1222. stamp.close();
  1223. pdfReader.close();
  1224.  
  1225. destinationNode = createDestinationNode(fileName,
  1226. (NodeRef)params.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  1227. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  1228.  
  1229. writer.setEncoding(targetReader.getEncoding());
  1230. writer.setMimetype(FILE_MIMETYPE);
  1231.  
  1232. // Put it in the repository
  1233. writer.putContent(file);
  1234.  
  1235. // Clean up
  1236. file.delete();
  1237.  
  1238. }
  1239. catch (IOException e)
  1240. {
  1241. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1242. }
  1243. catch (DocumentException e)
  1244. {
  1245. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1246. }
  1247. catch (Exception e)
  1248. {
  1249. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1250. }
  1251. finally
  1252. {
  1253. if (pdfReader != null)
  1254. {
  1255. pdfReader.close();
  1256. }
  1257. if (is != null)
  1258. {
  1259. try
  1260. {
  1261. is.close();
  1262. }
  1263. catch (IOException e)
  1264. {
  1265. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1266. }
  1267. }
  1268.  
  1269. if (tempDir != null)
  1270. {
  1271. tempDir.delete();
  1272. }
  1273. }
  1274. return destinationNode;
  1275. }
  1276.  
  1277. private NodeRef subsetPDFDocument(NodeRef targetNodeRef, Map<String, Serializable> params, String pages, boolean inplace, boolean delete)
  1278. {
  1279. InputStream is = null;
  1280. File tempDir = null;
  1281. ContentWriter writer = null;
  1282. PdfReader pdfReader = null;
  1283. NodeRef destinationNode = null;
  1284.  
  1285. try
  1286. {
  1287. ContentReader targetReader = getReader(targetNodeRef);
  1288. is = targetReader.getContentInputStream();
  1289.  
  1290. File alfTempDir = TempFileProvider.getTempDir();
  1291. tempDir = new File(alfTempDir.getPath() + File.separatorChar + targetNodeRef.getId());
  1292. tempDir.mkdir();
  1293.  
  1294. //Boolean inplace = inplace;
  1295.  
  1296. String fileName = getFilename(params, targetNodeRef);
  1297.  
  1298. File file = new File(tempDir, ffs.getFileInfo(targetNodeRef).getName());
  1299.  
  1300. pdfReader = new PdfReader(is);
  1301. Document doc = new Document(pdfReader.getPageSizeWithRotation(1));
  1302. PdfCopy copy = new PdfCopy(doc, new FileOutputStream(file));
  1303. doc.open();
  1304.  
  1305. List<Integer> pagelist = parsePageList(pages);
  1306.  
  1307. for (int pageNum = 1; pageNum <= pdfReader.getNumberOfPages(); pageNum++)
  1308. {
  1309. if (pagelist.contains(pageNum) && !delete)
  1310. {
  1311. copy.addPage(copy.getImportedPage(pdfReader, pageNum));
  1312. }
  1313. else if (!pagelist.contains(pageNum) && delete)
  1314. {
  1315. copy.addPage(copy.getImportedPage(pdfReader, pageNum));
  1316. }
  1317. }
  1318. doc.close();
  1319.  
  1320. destinationNode = createDestinationNode(fileName,
  1321. (NodeRef)params.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  1322. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  1323.  
  1324. writer.setEncoding(targetReader.getEncoding());
  1325. writer.setMimetype(FILE_MIMETYPE);
  1326.  
  1327. // Put it in the repository
  1328. writer.putContent(file);
  1329.  
  1330. // Clean up
  1331. file.delete();
  1332.  
  1333. }
  1334. catch (IOException e)
  1335. {
  1336. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1337. }
  1338. catch (DocumentException e)
  1339. {
  1340. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1341. }
  1342. catch (Exception e)
  1343. {
  1344. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1345. }
  1346. finally
  1347. {
  1348. if (pdfReader != null)
  1349. {
  1350. pdfReader.close();
  1351. }
  1352. if (is != null)
  1353. {
  1354. try
  1355. {
  1356. is.close();
  1357. }
  1358. catch (IOException e)
  1359. {
  1360. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1361. }
  1362. }
  1363.  
  1364. if (tempDir != null)
  1365. {
  1366. tempDir.delete();
  1367. }
  1368. }
  1369. return destinationNode;
  1370. }
  1371.  
  1372. private ContentReader getReader(NodeRef nodeRef)
  1373. {
  1374. // first, make sure the node exists
  1375. if (ns.exists(nodeRef) == false)
  1376. {
  1377. // node doesn't exist - can't do anything
  1378. throw new AlfrescoRuntimeException("NodeRef: " + nodeRef + " does not exist");
  1379. }
  1380.  
  1381. // Next check that the node is a sub-type of content
  1382. QName typeQName = ns.getType(nodeRef);
  1383. if (ds.isSubClass(typeQName, ContentModel.TYPE_CONTENT) == false)
  1384. {
  1385. // it is not content, so can't transform
  1386. throw new AlfrescoRuntimeException("The selected node is not a content node");
  1387. }
  1388.  
  1389. // Get the content reader. If it is null, can't do anything here
  1390. ContentReader contentReader = cs.getReader(nodeRef, ContentModel.PROP_CONTENT);
  1391.  
  1392. if(contentReader == null)
  1393. {
  1394. throw new AlfrescoRuntimeException("The content reader for NodeRef: " + nodeRef + "is null");
  1395. }
  1396.  
  1397. return contentReader;
  1398. }
  1399.  
  1400. /**
  1401. * @param ruleAction
  1402. * @param filename
  1403. * @return
  1404. */
  1405. private NodeRef createDestinationNode(String filename, NodeRef destinationParent, NodeRef target, boolean inplace)
  1406. {
  1407.  
  1408. NodeRef destinationNode;
  1409.  
  1410. // if inplace mode is turned on, the destination for the modified content
  1411. // is the original node
  1412. if(inplace)
  1413. {
  1414. return target;
  1415. }
  1416.  
  1417. if(createNew)
  1418. {
  1419. //create a file in the right location
  1420. FileInfo fileInfo = ffs.create(destinationParent, filename, ContentModel.TYPE_CONTENT);
  1421. destinationNode = fileInfo.getNodeRef();
  1422. }
  1423. else
  1424. {
  1425. try
  1426. {
  1427. FileInfo fileInfo = ffs.copy(target, destinationParent, filename);
  1428. destinationNode = fileInfo.getNodeRef();
  1429. }
  1430. catch(FileNotFoundException fnf)
  1431. {
  1432. throw new AlfrescoRuntimeException(fnf.getMessage(), fnf);
  1433. }
  1434. }
  1435.  
  1436. return destinationNode;
  1437. }
  1438.  
  1439. private int getInteger(Serializable val)
  1440. {
  1441. if(val == null)
  1442. {
  1443. return 0;
  1444. }
  1445. try
  1446. {
  1447. return Integer.parseInt(val.toString());
  1448. }
  1449. catch(NumberFormatException nfe)
  1450. {
  1451. return 0;
  1452. }
  1453. }
  1454.  
  1455. private File getTempFile(NodeRef nodeRef)
  1456. {
  1457. File alfTempDir = TempFileProvider.getTempDir();
  1458. File toolkitTempDir = new File(alfTempDir.getPath() + File.separatorChar + nodeRef.getId());
  1459. toolkitTempDir.mkdir();
  1460. File file = new File(toolkitTempDir, ffs.getFileInfo(nodeRef).getName());
  1461.  
  1462. return file;
  1463. }
  1464.  
  1465. private String getFilename(Map<String, Serializable> params, NodeRef targetNodeRef)
  1466. {
  1467. Serializable providedName = params.get(PARAM_DESTINATION_NAME);
  1468. String fileName = null;
  1469. if(providedName != null)
  1470. {
  1471. fileName = String.valueOf(providedName);
  1472. if(!fileName.endsWith(FILE_EXTENSION))
  1473. {
  1474. fileName = fileName + FILE_EXTENSION;
  1475. }
  1476. }
  1477. else
  1478. {
  1479. fileName = String.valueOf(ns.getProperty(targetNodeRef, ContentModel.PROP_NAME));
  1480. }
  1481. return fileName;
  1482. }
  1483.  
  1484. /**
  1485. * Parses the list of pages or page ranges to delete and returns a list of page numbers
  1486. *
  1487. * @param list
  1488. * @return
  1489. */
  1490. private List<Integer> parsePageList(String list)
  1491. {
  1492. List<Integer> pages = new ArrayList<Integer>();
  1493. String[] tokens = list.split(",");
  1494. for(String token : tokens)
  1495. {
  1496. //parse each, if one is not an int, log it but keep going
  1497. try
  1498. {
  1499. pages.add(Integer.parseInt(token));
  1500. }
  1501. catch(NumberFormatException nfe)
  1502. {
  1503. logger.warn("Page list contains non-numeric values");
  1504. }
  1505. }
  1506. return pages;
  1507. }
  1508.  
  1509. /**
  1510. * Build the permissions mask for iText
  1511. *
  1512. * @param options
  1513. * @return
  1514. */
  1515. private int buildPermissionMask(Map<String, Serializable> options)
  1516. {
  1517. int permissions = 0;
  1518.  
  1519. if ((Boolean)options.get(PARAM_ALLOW_PRINT))
  1520. {
  1521. permissions = permissions | PdfWriter.ALLOW_PRINTING;
  1522. }
  1523. if ((Boolean)options.get(PARAM_ALLOW_COPY))
  1524. {
  1525. permissions = permissions | PdfWriter.ALLOW_COPY;
  1526. }
  1527. if ((Boolean)options.get(PARAM_ALLOW_CONTENT_MODIFICATION))
  1528. {
  1529. permissions = permissions | PdfWriter.ALLOW_MODIFY_CONTENTS;
  1530. }
  1531. if ((Boolean)options.get(PARAM_ALLOW_ANNOTATION_MODIFICATION))
  1532. {
  1533. permissions = permissions | PdfWriter.ALLOW_MODIFY_ANNOTATIONS;
  1534. }
  1535. if ((Boolean)options.get(PARAM_ALLOW_SCREEN_READER))
  1536. {
  1537. permissions = permissions | PdfWriter.ALLOW_SCREENREADERS;
  1538. }
  1539. if ((Boolean)options.get(PARAM_ALLOW_DEGRADED_PRINT))
  1540. {
  1541. permissions = permissions | PdfWriter.ALLOW_DEGRADED_PRINTING;
  1542. }
  1543. if ((Boolean)options.get(PARAM_ALLOW_ASSEMBLY))
  1544. {
  1545. permissions = permissions | PdfWriter.ALLOW_ASSEMBLY;
  1546. }
  1547. if ((Boolean)options.get(PARAM_ALLOW_FORM_FILL))
  1548. {
  1549. permissions = permissions | PdfWriter.ALLOW_FILL_IN;
  1550. }
  1551.  
  1552. return permissions;
  1553. }
  1554.  
  1555. /**
  1556. * Create a rectangle for the visible signature using the selected position and signature size
  1557. *
  1558. * @param position
  1559. * @param width
  1560. * @param height
  1561. * @return
  1562. */
  1563. private Rectangle positionSignature(String position, Rectangle pageRect, int width, int height)
  1564. {
  1565.  
  1566. float pageHeight = pageRect.getHeight();
  1567. float pageWidth = pageRect.getWidth();
  1568.  
  1569. Rectangle r = null;
  1570.  
  1571. if (position.equals(POSITION_BOTTOMLEFT))
  1572. {
  1573. r = new Rectangle(0, height, width, 0);
  1574. }
  1575. else if (position.equals(POSITION_BOTTOMRIGHT))
  1576. {
  1577. r = new Rectangle(pageWidth - width, height, pageWidth, 0);
  1578. }
  1579. else if (position.equals(POSITION_TOPLEFT))
  1580. {
  1581. r = new Rectangle(0, pageHeight, width, pageHeight - height);
  1582. }
  1583. else if (position.equals(POSITION_TOPRIGHT))
  1584. {
  1585. r = new Rectangle(pageWidth - width, pageHeight, pageWidth, pageHeight - height);
  1586. }
  1587. else if (position.equals(POSITION_CENTER))
  1588. {
  1589. r = new Rectangle((pageWidth / 2) - (width / 2), (pageHeight / 2) - (height / 2),
  1590. (pageWidth / 2) + (width / 2), (pageHeight / 2) + (height / 2));
  1591. }
  1592.  
  1593. return r;
  1594. }
  1595.  
  1596. /**
  1597. * @param fileName
  1598. * @param extension
  1599. * @return
  1600. */
  1601. private String removeExtension(String fileName, String extension)
  1602. {
  1603. // Does the file have the extension?
  1604. if (fileName != null && fileName.contains(extension))
  1605. {
  1606. // Where does the extension start?
  1607. int extensionStartsAt = fileName.indexOf(extension);
  1608. // Get the Filename sans the extension
  1609. return fileName.substring(0, extensionStartsAt);
  1610. }
  1611.  
  1612. return fileName;
  1613. }
  1614.  
  1615. private String getFilename(NodeRef targetNodeRef)
  1616. {
  1617. FileInfo fileInfo = ffs.getFileInfo(targetNodeRef);
  1618. String filename = fileInfo.getName();
  1619.  
  1620. return filename;
  1621. }
  1622.  
  1623. private String getFilenameSansExt(NodeRef targetNodeRef, String extension)
  1624. {
  1625. String filenameSansExt;
  1626. filenameSansExt = removeExtension(getFilename(targetNodeRef), extension);
  1627.  
  1628. return filenameSansExt;
  1629. }
  1630.  
  1631. /**
  1632. * Applies an image watermark
  1633. *
  1634. * @param reader
  1635. * @param writer
  1636. * @param options
  1637. * @throws Exception
  1638. */
  1639. private NodeRef imageAction(Map<String, Serializable> options, NodeRef targetNodeRef, NodeRef watermarkNodeRef,
  1640. ContentReader actionedUponContentReader, ContentReader watermarkContentReader)
  1641. {
  1642.  
  1643. PdfStamper stamp = null;
  1644. File tempDir = null;
  1645. ContentWriter writer = null;
  1646. NodeRef destinationNode = null;
  1647.  
  1648. try
  1649. {
  1650. File file = getTempFile(targetNodeRef);
  1651.  
  1652. // get the PDF input stream and create a reader for iText
  1653. PdfReader reader = new PdfReader(actionedUponContentReader.getContentInputStream());
  1654. stamp = new PdfStamper(reader, new FileOutputStream(file));
  1655. PdfContentByte pcb;
  1656.  
  1657. // get a com.itextpdf.text.Image object via java.imageio.ImageIO
  1658. Image img = Image.getInstance(ImageIO.read(watermarkContentReader.getContentInputStream()), null);
  1659.  
  1660. // get the PDF pages and position
  1661. String pages = (String)options.get(PARAM_PAGE);
  1662. String position = (String)options.get(PARAM_POSITION);
  1663. String depth = (String)options.get(PARAM_WATERMARK_DEPTH);
  1664. Boolean inplace = true;
  1665.  
  1666. // get the manual positioning options (if provided)
  1667. int locationX = getInteger(options.get(PARAM_LOCATION_X));
  1668. int locationY = getInteger(options.get(PARAM_LOCATION_Y));
  1669.  
  1670. // image requires absolute positioning or an exception will be
  1671. // thrown
  1672. // set image position according to parameter. Use
  1673. // PdfReader.getPageSizeWithRotation
  1674. // to get the canvas size for alignment.
  1675. img.setAbsolutePosition(100f, 100f);
  1676.  
  1677. // stamp each page
  1678. int numpages = reader.getNumberOfPages();
  1679. for (int i = 1; i <= numpages; i++)
  1680. {
  1681. Rectangle r = reader.getPageSizeWithRotation(i);
  1682. // set stamp position
  1683. if (position.equals(POSITION_BOTTOMLEFT))
  1684. {
  1685. img.setAbsolutePosition(0, 0);
  1686. }
  1687. else if (position.equals(POSITION_BOTTOMRIGHT))
  1688. {
  1689. img.setAbsolutePosition(r.getWidth() - img.getWidth(), 0);
  1690. }
  1691. else if (position.equals(POSITION_TOPLEFT))
  1692. {
  1693. img.setAbsolutePosition(0, r.getHeight() - img.getHeight());
  1694. }
  1695. else if (position.equals(POSITION_TOPRIGHT))
  1696. {
  1697. img.setAbsolutePosition(r.getWidth() - img.getWidth(), r.getHeight() - img.getHeight());
  1698. }
  1699. else if (position.equals(POSITION_CENTER))
  1700. {
  1701. img.setAbsolutePosition(getCenterX(r, img), getCenterY(r, img));
  1702. }
  1703. else if (position.equals(POSITION_MANUAL))
  1704. {
  1705. img.setAbsolutePosition(locationX, locationY);
  1706. }
  1707.  
  1708. // if this is an under-text stamp, use getUnderContent.
  1709. // if this is an over-text stamp, usse getOverContent.
  1710. if (depth.equals(DEPTH_OVER))
  1711. {
  1712. pcb = stamp.getOverContent(i);
  1713. }
  1714. else
  1715. {
  1716. pcb = stamp.getUnderContent(i);
  1717. }
  1718.  
  1719. // only apply stamp to requested pages
  1720. if (checkPage(pages, i, numpages))
  1721. {
  1722. pcb.addImage(img);
  1723. }
  1724. }
  1725.  
  1726. stamp.close();
  1727.  
  1728. String fileName = getFilename(options, targetNodeRef);
  1729.  
  1730. // Get a writer and prep it for putting it back into the repo
  1731. //can't use BasePDFActionExecuter.getWriter here need the nodeRef of the destination
  1732. destinationNode = createDestinationNode(fileName,
  1733. (NodeRef)options.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  1734. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  1735.  
  1736. writer.setEncoding(actionedUponContentReader.getEncoding());
  1737. writer.setMimetype(FILE_MIMETYPE);
  1738.  
  1739. // Put it in the repo
  1740. writer.putContent(file);
  1741.  
  1742. // delete the temp file
  1743. file.delete();
  1744. }
  1745. catch (IOException e)
  1746. {
  1747. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1748. }
  1749. catch (DocumentException e)
  1750. {
  1751. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1752. }
  1753. finally
  1754. {
  1755. if (tempDir != null)
  1756. {
  1757. try
  1758. {
  1759. tempDir.delete();
  1760. }
  1761. catch (Exception ex)
  1762. {
  1763. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  1764. }
  1765. }
  1766.  
  1767. if (stamp != null)
  1768. {
  1769. try
  1770. {
  1771. stamp.close();
  1772. }
  1773. catch (Exception ex)
  1774. {
  1775. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  1776. }
  1777. }
  1778. }
  1779.  
  1780. return destinationNode;
  1781. }
  1782.  
  1783.  
  1784. /**
  1785. * Applies a text watermark (current date, user name, etc, depending on
  1786. * options)
  1787. *
  1788. * @param reader
  1789. * @param writer
  1790. * @param options
  1791. */
  1792. private NodeRef textAction(Map<String, Serializable> options, NodeRef targetNodeRef, ContentReader actionedUponContentReader)
  1793. {
  1794.  
  1795. PdfStamper stamp = null;
  1796. File tempDir = null;
  1797. ContentWriter writer = null;
  1798. String watermarkText;
  1799. StringTokenizer st;
  1800. Vector<String> tokens = new Vector<String>();
  1801. NodeRef destinationNode = null;
  1802.  
  1803. try
  1804. {
  1805. File file = getTempFile(targetNodeRef);
  1806.  
  1807. // get the PDF input stream and create a reader for iText
  1808. PdfReader reader = new PdfReader(actionedUponContentReader.getContentInputStream());
  1809. stamp = new PdfStamper(reader, new FileOutputStream(file));
  1810. PdfContentByte pcb;
  1811.  
  1812. // get the PDF pages and position
  1813. String pages = (String)options.get(PARAM_PAGE);
  1814. String position = (String)options.get(PARAM_POSITION);
  1815. String depth = (String)options.get(PARAM_WATERMARK_DEPTH);
  1816. int locationX = getInteger(options.get(PARAM_LOCATION_X));
  1817. int locationY = getInteger(options.get(PARAM_LOCATION_Y));
  1818. Boolean inplace = true;
  1819.  
  1820. // create the base font for the text stamp
  1821. BaseFont bf = BaseFont.createFont((String)options.get(PARAM_WATERMARK_FONT), BaseFont.CP1250, BaseFont.EMBEDDED);
  1822.  
  1823. // get watermark text and process template with model
  1824. String templateText = (String)options.get(PARAM_WATERMARK_TEXT);
  1825. Map<String, Object> model = buildWatermarkTemplateModel(targetNodeRef);
  1826. StringWriter watermarkWriter = new StringWriter();
  1827. freemarkerProcessor.processString(templateText, model, watermarkWriter);
  1828. watermarkText = watermarkWriter.getBuffer().toString();
  1829.  
  1830. // tokenize watermark text to support multiple lines and copy tokens
  1831. // to vector for re-use
  1832. st = new StringTokenizer(watermarkText, "\r\n", false);
  1833. while (st.hasMoreTokens())
  1834. {
  1835. tokens.add(st.nextToken());
  1836. }
  1837.  
  1838. // stamp each page
  1839. int numpages = reader.getNumberOfPages();
  1840. for (int i = 1; i <= numpages; i++)
  1841. {
  1842. Rectangle r = reader.getPageSizeWithRotation(i);
  1843.  
  1844. // if this is an under-text stamp, use getUnderContent.
  1845. // if this is an over-text stamp, use getOverContent.
  1846. if (depth.equals(DEPTH_OVER))
  1847. {
  1848. pcb = stamp.getOverContent(i);
  1849. }
  1850. else
  1851. {
  1852. pcb = stamp.getUnderContent(i);
  1853. }
  1854.  
  1855. // set the font and size
  1856. float size = Float.parseFloat((String)options.get(PARAM_WATERMARK_SIZE));
  1857. pcb.setFontAndSize(bf, size);
  1858.  
  1859. // only apply stamp to requested pages
  1860. if (checkPage(pages, i, numpages))
  1861. {
  1862. writeAlignedText(pcb, r, tokens, size, position, locationX, locationY);
  1863. }
  1864. }
  1865.  
  1866. stamp.close();
  1867.  
  1868. String fileName = getFilename(options, targetNodeRef);
  1869.  
  1870. // Get a writer and prep it for putting it back into the repo
  1871. //can't use BasePDFActionExecuter.getWriter here need the nodeRef of the destination
  1872. destinationNode = createDestinationNode(fileName,
  1873. (NodeRef)options.get(PARAM_DESTINATION_FOLDER), targetNodeRef, inplace);
  1874. writer = cs.getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
  1875. writer.setEncoding(actionedUponContentReader.getEncoding());
  1876. writer.setMimetype(FILE_MIMETYPE);
  1877.  
  1878. // Put it in the repo
  1879. writer.putContent(file);
  1880.  
  1881. // delete the temp file
  1882. file.delete();
  1883. }
  1884. catch (IOException e)
  1885. {
  1886. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1887. }
  1888. catch (DocumentException e)
  1889. {
  1890. throw new AlfrescoRuntimeException(e.getMessage(), e);
  1891. }
  1892. finally
  1893. {
  1894. if (tempDir != null)
  1895. {
  1896. try
  1897. {
  1898. tempDir.delete();
  1899. }
  1900. catch (Exception ex)
  1901. {
  1902. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  1903. }
  1904. }
  1905.  
  1906. if (stamp != null)
  1907. {
  1908. try
  1909. {
  1910. stamp.close();
  1911. }
  1912. catch (Exception ex)
  1913. {
  1914. throw new AlfrescoRuntimeException(ex.getMessage(), ex);
  1915. }
  1916. }
  1917. }
  1918.  
  1919. return destinationNode;
  1920. }
  1921.  
  1922.  
  1923. /**
  1924. * Writes text watermark to one of the 5 preconfigured locations
  1925. *
  1926. * @param pcb
  1927. * @param r
  1928. * @param tokens
  1929. * @param size
  1930. * @param position
  1931. */
  1932. private void writeAlignedText(PdfContentByte pcb, Rectangle r, Vector<String> tokens, float size,
  1933. String position, int locationX, int locationY)
  1934. {
  1935. // get the dimensions of our 'rectangle' for text
  1936. float height = size * tokens.size();
  1937. float width = 0;
  1938. float centerX = 0, startY = 0;
  1939. for (int i = 0; i < tokens.size(); i++)
  1940. {
  1941. if (pcb.getEffectiveStringWidth(tokens.get(i), false) > width)
  1942. {
  1943. width = pcb.getEffectiveStringWidth(tokens.get(i), false);
  1944. }
  1945. }
  1946.  
  1947. // now that we have the width and height, we can calculate the center
  1948. // position for
  1949. // the rectangle that will contain our text.
  1950. if (position.equals(POSITION_BOTTOMLEFT))
  1951. {
  1952. centerX = width / 2 + PAD;
  1953. startY = 0 + PAD + height;
  1954. }
  1955. else if (position.equals(POSITION_BOTTOMRIGHT))
  1956. {
  1957. centerX = r.getWidth() - (width / 2) - PAD;
  1958. startY = 0 + PAD + height;
  1959. }
  1960. else if (position.equals(POSITION_TOPLEFT))
  1961. {
  1962. centerX = width / 2 + PAD;
  1963. startY = r.getHeight() - (PAD * 2);
  1964. }
  1965. else if (position.equals(POSITION_TOPRIGHT))
  1966. {
  1967. centerX = r.getWidth() - (width / 2) - PAD;
  1968. startY = r.getHeight() - (PAD * 2);
  1969. }
  1970. else if (position.equals(POSITION_CENTER))
  1971. {
  1972. centerX = r.getWidth() / 2;
  1973. startY = (r.getHeight() / 2) + (height / 2);
  1974. }
  1975. else if (position.equals(POSITION_MANUAL))
  1976. {
  1977. centerX = r.getWidth() / 2 - locationX;
  1978. startY = locationY;
  1979. }
  1980.  
  1981. // apply text to PDF
  1982. pcb.beginText();
  1983.  
  1984. for (int t = 0; t < tokens.size(); t++)
  1985. {
  1986. pcb.showTextAligned(PdfContentByte.ALIGN_CENTER, tokens.get(t), centerX, startY - (size * t), 0);
  1987. }
  1988.  
  1989. pcb.endText();
  1990.  
  1991. }
  1992.  
  1993. /**
  1994. * Builds a freemarker model which supports a subset of the default model.
  1995. *
  1996. * @param ref
  1997. * @return
  1998. */
  1999. private Map<String, Object> buildWatermarkTemplateModel(NodeRef ref)
  2000. {
  2001. Map<String, Object> model = new HashMap<String, Object>();
  2002.  
  2003. NodeRef person = ps.getPerson(as.getCurrentUserName());
  2004. model.put("person", new TemplateNode(person, serviceRegistry, null));
  2005. NodeRef homespace = (NodeRef)ns.getProperty(person, ContentModel.PROP_HOMEFOLDER);
  2006. model.put("userhome", new TemplateNode(homespace, serviceRegistry, null));
  2007. model.put("document", new TemplateNode(ref, serviceRegistry, null));
  2008. NodeRef parent = ns.getPrimaryParent(ref).getParentRef();
  2009. model.put("space", new TemplateNode(parent, serviceRegistry, null));
  2010. model.put("date", new Date());
  2011.  
  2012. //also add all of the node properties to the model
  2013. model.put("properties", ns.getProperties(ref));
  2014.  
  2015. return model;
  2016. }
  2017.  
  2018. /**
  2019. * Determines whether or not a watermark should be applied to a given page
  2020. *
  2021. * @param pages
  2022. * @param current
  2023. * @param numpages
  2024. * @return
  2025. */
  2026. private boolean checkPage(String pages, int current, int numpages)
  2027. {
  2028.  
  2029.  
  2030. boolean markPage = false;
  2031.  
  2032. if (pages.equals(PAGE_EVEN))
  2033. {
  2034. if (current % 2 == 0)
  2035. {
  2036. markPage = true;
  2037. }
  2038. }
  2039. else if (pages.equals(PAGE_ODD))
  2040. {
  2041. if (current % 2 != 0)
  2042. {
  2043. markPage = true;
  2044. }
  2045. }
  2046. else if (pages.equals(PAGE_FIRST))
  2047. {
  2048. if (current == 1)
  2049. {
  2050. markPage = true;
  2051. }
  2052. }
  2053. else if (pages.equals(PAGE_LAST))
  2054. {
  2055. if (current == numpages)
  2056. {
  2057. markPage = true;
  2058. }
  2059. }
  2060. else if (pages.equals(PAGE_ALL))
  2061. {
  2062. markPage = true;
  2063. }
  2064. else
  2065. {
  2066. // if we get here, a scheme wasn't selected, so we can treat this like a page list
  2067. List<Integer> pageList = parsePageList(pages);
  2068. if(pageList.contains(current))
  2069. {
  2070. markPage = true;
  2071. }
  2072. }
  2073.  
  2074. return markPage;
  2075. }
  2076.  
  2077. /**
  2078. * Gets the X value for centering the watermark image
  2079. *
  2080. * @param r
  2081. * @param img
  2082. * @return
  2083. */
  2084. private float getCenterX(Rectangle r, Image img)
  2085. {
  2086. float x = 0;
  2087. float pdfwidth = r.getWidth();
  2088. float imgwidth = img.getWidth();
  2089.  
  2090. x = (pdfwidth - imgwidth) / 2;
  2091.  
  2092. return x;
  2093. }
  2094.  
  2095. /**
  2096. * Gets the Y value for centering the watermark image
  2097. *
  2098. * @param r
  2099. * @param img
  2100. * @return
  2101. */
  2102. private float getCenterY(Rectangle r, Image img)
  2103. {
  2104. float y = 0;
  2105. float pdfheight = r.getHeight();
  2106. float imgheight = img.getHeight();
  2107.  
  2108. y = (pdfheight - imgheight) / 2;
  2109.  
  2110. return y;
  2111. }
  2112.  
  2113. /**
  2114. * @param serviceRegistry
  2115. */
  2116. public void setServiceRegistry(ServiceRegistry serviceRegistry)
  2117. {
  2118. this.serviceRegistry = serviceRegistry;
  2119. ns = serviceRegistry.getNodeService();
  2120. cs = serviceRegistry.getContentService();
  2121. ffs = serviceRegistry.getFileFolderService();
  2122. ds = serviceRegistry.getDictionaryService();
  2123. ps = serviceRegistry.getPersonService();
  2124. as = serviceRegistry.getAuthenticationService();
  2125. }
  2126.  
  2127. /**
  2128. * Sets whether a PDF action creates a new empty node or copies the source node, preserving
  2129. * the content type, applied aspects and properties
  2130. *
  2131. * @param createNew
  2132. */
  2133. public void setCreateNew(boolean createNew)
  2134. {
  2135. this.createNew = createNew;
  2136. }
  2137.  
  2138. public void setUseSignatureAspect(boolean useSignatureAspect)
  2139. {
  2140. this.useSignatureAspect = useSignatureAspect;
  2141. }
  2142.  
  2143. public void setUseEncryptionAspect(boolean useEncryptionAspect)
  2144. {
  2145. this.useEncryptionAspect = useEncryptionAspect;
  2146. }
  2147.  
  2148. public void setCheckOutCheckInService(
  2149. CheckOutCheckInService checkOutCheckinService) {
  2150. this.checkOutCheckInService = checkOutCheckinService;
  2151. }
  2152. }
Add Comment
Please, Sign In to add comment