/** * Create a M2Model from a dictionary model node * * @param nodeRef the dictionary model node reference * @return the M2Model */ public M2Model createM2Model(NodeRef nodeRef) { M2Model model = null; ContentReader contentReader = this.contentService.getReader(nodeRef, ContentModel.PROP_CONTENT); if (contentReader != null) { if (contentReader instanceof EmptyContentReader) { // belts-and-braces logger.error("Failed to create model (due to EmptyContentReader): " + nodeRef); } else { InputStream is = null; try { is = contentReader.getContentInputStream(); model = M2Model.createModel(is); } finally { if (is != null) { try { is.close(); } catch (IOException e) { logger.error("Failed to close input stream for " + nodeRef); } } } } } // TODO should we inactivate the model node and put the error somewhere?? return model; }
/** Asks Tika to translate the contents into HTML */ private void generateHTML(Parser p, RenderingContext context) { ContentReader contentReader = context.makeContentReader(); // Setup things to parse with StringWriter sw = new StringWriter(); ContentHandler handler = buildContentHandler(sw, context); // Tell Tika what we're dealing with Metadata metadata = new Metadata(); metadata.set(Metadata.CONTENT_TYPE, contentReader.getMimetype()); metadata.set( Metadata.RESOURCE_NAME_KEY, nodeService.getProperty(context.getSourceNode(), ContentModel.PROP_NAME).toString()); // Our parse context needs to extract images ParseContext parseContext = new ParseContext(); parseContext.set(Parser.class, new TikaImageExtractingParser(context)); // Parse try { p.parse(contentReader.getContentInputStream(), handler, metadata, parseContext); } catch (Exception e) { throw new RenditionServiceException("Tika HTML Conversion Failed", e); } // As a string String html = sw.toString(); // If we're doing body-only, remove all the html namespaces // that will otherwise clutter up the document boolean bodyOnly = context.getParamWithDefault(PARAM_BODY_CONTENTS_ONLY, false); if (bodyOnly) { html = html.replaceAll("<\\?xml.*?\\?>", ""); html = html.replaceAll("<p xmlns=\"http://www.w3.org/1999/xhtml\"", "<p"); html = html.replaceAll("<h(\\d) xmlns=\"http://www.w3.org/1999/xhtml\"", "<h\\1"); html = html.replaceAll("<div xmlns=\"http://www.w3.org/1999/xhtml\"", "<div"); html = html.replaceAll("<table xmlns=\"http://www.w3.org/1999/xhtml\"", "<table"); html = html.replaceAll(" ", ""); } // Save it ContentWriter contentWriter = context.makeContentWriter(); contentWriter.setMimetype("text/html"); contentWriter.putContent(html); }
/** * get document from wcm content * * @param path * @return document * @throws ServiceException */ public InputStream getContent(String path) { InputStream retStream = null; PersistenceManagerService persistenceManagerService = _servicesManager.getService(PersistenceManagerService.class); NodeRef nodeRef = persistenceManagerService.getNodeRef(path); if (nodeRef != null) { FileInfo fileInfo = persistenceManagerService.getFileInfo(nodeRef); if (fileInfo.isFolder()) { logger.info(MSG_CONTENT_FOR_FOLDER_REQUESTED, path); } else { ContentReader reader = persistenceManagerService.getReader(nodeRef); retStream = reader.getContentInputStream(); } } else { logger.info(MSG_NODE_REF_IS_NULL_FOR_PATH, path); } return retStream; }
/** * Send an email message * * @throws AlfrescoRuntimeExeption */ @SuppressWarnings("unchecked") @Override protected void executeImpl(final Action ruleAction, final NodeRef actionedUponNodeRef) { try { MimeMessage message = javaMailSender.createMimeMessage(); // use the true flag to indicate you need a multipart message MimeMessageHelper helper = new MimeMessageHelper(message, true); // set recipient String to = (String) ruleAction.getParameterValue(PARAM_TO); if (to != null && to.length() != 0) { helper.setTo(to); } else { // see if multiple recipients have been supplied - as a list of // authorities Serializable toManyMails = ruleAction.getParameterValue(PARAM_TO_MANY); List<String> recipients = new ArrayList<String>(); if (toManyMails instanceof List) { for (String mailAdress : (List<String>) toManyMails) { if (validateAddress(mailAdress)) { recipients.add(mailAdress); } } } else if (toManyMails instanceof String) { if (validateAddress((String) toManyMails)) { recipients.add((String) toManyMails); } } if (recipients != null && recipients.size() > 0) { helper.setTo(recipients.toArray(new String[recipients.size()])); } else { // No recipients have been specified logger.error("No recipient has been specified for the mail action"); } } // set subject line helper.setSubject((String) ruleAction.getParameterValue(PARAM_SUBJECT)); // See if an email template has been specified String text = null; NodeRef templateRef = (NodeRef) ruleAction.getParameterValue(PARAM_TEMPLATE); if (templateRef != null) { // build the email template model Map<String, Object> model = createEmailTemplateModel(actionedUponNodeRef, ruleAction); // process the template against the model text = templateService.processTemplate("freemarker", templateRef.toString(), model); } // set the text body of the message if (text == null) { text = (String) ruleAction.getParameterValue(PARAM_TEXT); } // adding the boolean true to send as HTML helper.setText(text, true); FileFolderService fileFolderService = serviceRegistry.getFileFolderService(); /* add inline images. * "action.parameters.images is a ,-delimited string, containing a map of images and resources, from this example: message.setText("my text <img src='cid:myLogo'>", true); message.addInline("myLogo", new ClassPathResource("img/mylogo.gif")); so the "images" param can look like this: headerLogo|images/headerLogoNodeRef,footerLogo|footerLogoNodeRef */ String imageList = (String) ruleAction.getParameterValue(PARAM_IMAGES); System.out.println(imageList); String[] imageMap = imageList.split(","); // comma no spaces Map<String, String> images = new HashMap<String, String>(); for (String image : imageMap) { System.out.println(image); String map[] = image.split("\\|"); for (String key : map) { System.out.println(key); } System.out.println(map.length); images.put(map[0].trim(), map[1].trim()); System.out.println(images.size()); System.out.println("-" + map[0] + " " + map[1] + "-"); } NodeRef imagesFolderNodeRef = (NodeRef) ruleAction.getParameterValue(PARAM_IMAGES_FOLDER); if (null != imagesFolderNodeRef) { ContentService contentService = serviceRegistry.getContentService(); System.out.println("mapping"); for (Map.Entry<String, String> entry : images.entrySet()) { System.out.println( entry.getKey() + " " + entry.getValue() + " " + ruleAction.getParameterValue(PARAM_IMAGES_FOLDER)); NodeRef imageFile = fileFolderService.searchSimple(imagesFolderNodeRef, entry.getValue()); if (null != imageFile) { ContentReader reader = contentService.getReader(imageFile, ContentModel.PROP_CONTENT); ByteArrayResource resource = new ByteArrayResource(IOUtils.toByteArray(reader.getContentInputStream())); helper.addInline(entry.getKey(), resource, reader.getMimetype()); } else { logger.error("No image for " + entry.getKey()); } } } else { logger.error("No images folder"); } // set the from address NodeRef person = personService.getPerson(authService.getCurrentUserName()); String fromActualUser = null; if (person != null) { fromActualUser = (String) nodeService.getProperty(person, ContentModel.PROP_EMAIL); } if (fromActualUser != null && fromActualUser.length() != 0) { helper.setFrom(fromActualUser); } else { String from = (String) ruleAction.getParameterValue(PARAM_FROM); if (from == null || from.length() == 0) { helper.setFrom(fromAddress); } else { helper.setFrom(from); } } NodeRef attachmentsFolder = (NodeRef) ruleAction.getParameterValue(PARAM_ATTCHMENTS_FOLDER); if (attachmentsFolder != null) { List<FileInfo> attachFiles = fileFolderService.listFiles(attachmentsFolder); if (attachFiles != null && attachFiles.size() > 0) { for (FileInfo attachFile : attachFiles) { ContentReader contentReader = fileFolderService.getReader(attachFile.getNodeRef()); ByteArrayResource resource = new ByteArrayResource(IOUtils.toByteArray(contentReader.getContentInputStream())); helper.addAttachment(attachFile.getName(), resource, contentReader.getMimetype()); } } } // Send the message unless we are in "testMode" javaMailSender.send(message); } catch (Exception e) { String toUser = (String) ruleAction.getParameterValue(PARAM_TO); if (toUser == null) { Object obj = ruleAction.getParameterValue(PARAM_TO_MANY); if (obj != null) { toUser = obj.toString(); } } logger.error("Failed to send email to " + toUser, e); throw new AlfrescoRuntimeException("Failed to send email to:" + toUser, e); } }
public List<VerifyResultDTO> verifySign(final VerifyingDTO verifyingDTO) { final List<VerifyResultDTO> result = new ArrayList<VerifyResultDTO>(); try { if (verifyingDTO != null) { final String keyType = (String) nodeService.getProperty(verifyingDTO.getKeyFile(), SigningModel.PROP_KEYTYPE); final KeyStore ks = KeyStore.getInstance(keyType); final ContentReader keyContentReader = getReader(verifyingDTO.getKeyFile()); if (keyContentReader != null && ks != null && verifyingDTO.getKeyPassword() != null) { // Get crypted secret key and decrypt it final Serializable encryptedPropertyValue = nodeService.getProperty(verifyingDTO.getKeyFile(), SigningModel.PROP_KEYCRYPTSECRET); final Serializable decryptedPropertyValue = metadataEncryptor.decrypt(SigningModel.PROP_KEYCRYPTSECRET, encryptedPropertyValue); // Decrypt key content final InputStream decryptedKeyContent = CryptUtils.decrypt( decryptedPropertyValue.toString(), keyContentReader.getContentInputStream()); ks.load( new ByteArrayInputStream(IOUtils.toByteArray(decryptedKeyContent)), verifyingDTO.getKeyPassword().toCharArray()); final ContentReader fileToVerifyContentReader = getReader(verifyingDTO.getFileToVerify()); if (fileToVerifyContentReader != null) { final PdfReader reader = new PdfReader(fileToVerifyContentReader.getContentInputStream()); if (reader != null) { final AcroFields af = reader.getAcroFields(); if (af != null) { final ArrayList<String> names = af.getSignatureNames(); if (names != null) { for (int k = 0; k < names.size(); ++k) { final VerifyResultDTO verifyResultDTO = new VerifyResultDTO(); final String name = (String) names.get(k); verifyResultDTO.setName(name); verifyResultDTO.setSignatureCoversWholeDocument( af.signatureCoversWholeDocument(name)); verifyResultDTO.setRevision(af.getRevision(name)); verifyResultDTO.setTotalRevision(af.getTotalRevisions()); final PdfPKCS7 pk = af.verifySignature(name); if (pk != null) { final Calendar cal = pk.getSignDate(); final Certificate[] pkc = pk.getCertificates(); Object fails[] = PdfPKCS7.verifyCertificates(pkc, ks, null, cal); if (fails == null) { verifyResultDTO.setIsSignValid(true); } else { verifyResultDTO.setIsSignValid(false); verifyResultDTO.setFailReason(fails[1]); } verifyResultDTO.setSignSubject( PdfPKCS7.getSubjectFields(pk.getSigningCertificate()).toString()); verifyResultDTO.setIsDocumentModified(!pk.verify()); verifyResultDTO.setSignDate(pk.getSignDate()); verifyResultDTO.setSignLocation(pk.getLocation()); verifyResultDTO.setSignInformationVersion(pk.getSigningInfoVersion()); verifyResultDTO.setSignReason(pk.getReason()); verifyResultDTO.setSignVersion(pk.getVersion()); verifyResultDTO.setSignName(pk.getSignName()); result.add(verifyResultDTO); } else { log.error("Unable to verify signature."); throw new AlfrescoRuntimeException("Unable to verify signature."); } } } else { log.error("Unable to get signature names."); throw new AlfrescoRuntimeException("Unable to get signature names."); } } else { log.error("Unable to get PDF fields."); throw new AlfrescoRuntimeException("Unable to get PDF fields."); } } } else { log.error("Unable to get document to verify content."); throw new AlfrescoRuntimeException("Unable to get document to verify content."); } } else { log.error("Unable to get key content, key type or key password."); throw new AlfrescoRuntimeException( "Unable to get key content, key type or key password."); } } else { log.error("No object with verification informations."); throw new AlfrescoRuntimeException("No object with verification informations."); } } catch (KeyStoreException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (ContentIOException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (NoSuchAlgorithmException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (CertificateException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (IOException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (GeneralSecurityException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (Throwable e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } return result; }
/** * Sign file. * * @param signingDTO sign informations * @param pdfSignedFile signed pdf returned */ public void sign(final DigitalSigningDTO signingDTO) { if (signingDTO != null) { try { Security.addProvider(new BouncyCastleProvider()); final File alfTempDir = TempFileProvider.getTempDir(); if (alfTempDir != null) { final String keyType = (String) nodeService.getProperty(signingDTO.getKeyFile(), SigningModel.PROP_KEYTYPE); if (SigningConstants.KEY_TYPE_X509.equals(keyType)) { // Sign the file final KeyStore ks = KeyStore.getInstance("pkcs12"); final ContentReader keyContentReader = getReader(signingDTO.getKeyFile()); if (keyContentReader != null && ks != null && signingDTO.getKeyPassword() != null) { final List<AlfrescoRuntimeException> errors = new ArrayList<AlfrescoRuntimeException>(); // Get crypted secret key and decrypt it final Serializable encryptedPropertyValue = nodeService.getProperty( signingDTO.getKeyFile(), SigningModel.PROP_KEYCRYPTSECRET); final Serializable decryptedPropertyValue = metadataEncryptor.decrypt( SigningModel.PROP_KEYCRYPTSECRET, encryptedPropertyValue); // Decrypt key content InputStream decryptedKeyContent; try { decryptedKeyContent = CryptUtils.decrypt( decryptedPropertyValue.toString(), keyContentReader.getContentInputStream()); } catch (Throwable e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } ks.load( new ByteArrayInputStream(IOUtils.toByteArray(decryptedKeyContent)), signingDTO.getKeyPassword().toCharArray()); final String alias = (String) nodeService.getProperty(signingDTO.getKeyFile(), SigningModel.PROP_KEYALIAS); final PrivateKey key = (PrivateKey) ks.getKey(alias, signingDTO.getKeyPassword().toCharArray()); final Certificate[] chain = ks.getCertificateChain(alias); final Iterator<NodeRef> itFilesToSign = signingDTO.getFilesToSign().iterator(); while (itFilesToSign.hasNext()) { final NodeRef nodeRefToSign = itFilesToSign.next(); final AlfrescoRuntimeException exception = signFile(nodeRefToSign, signingDTO, alfTempDir, alias, ks, key, chain); if (exception != null) { // Error on the file process errors.add(exception); } } if (errors != null && errors.size() > 0) { final StringBuffer allErrors = new StringBuffer(); final Iterator<AlfrescoRuntimeException> itErrors = errors.iterator(); if (errors.size() > 1) { allErrors.append("\n"); } while (itErrors.hasNext()) { final AlfrescoRuntimeException alfrescoRuntimeException = itErrors.next(); allErrors.append(alfrescoRuntimeException.getMessage()); if (itErrors.hasNext()) { allErrors.append("\n"); } } throw new RuntimeException(allErrors.toString()); } } else { log.error("Unable to get key content, key type or key password."); throw new AlfrescoRuntimeException( "Unable to get key content, key type or key password."); } } } else { log.error("Unable to get temporary directory."); throw new AlfrescoRuntimeException("Unable to get temporary directory."); } } catch (KeyStoreException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (NoSuchAlgorithmException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (CertificateException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (IOException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (UnrecoverableKeyException e) { log.error(e); throw new AlfrescoRuntimeException(e.getMessage(), e); } } else { log.error("No object with signing informations."); throw new AlfrescoRuntimeException("No object with signing informations."); } }
private AlfrescoRuntimeException signFile( final NodeRef nodeRefToSign, final DigitalSigningDTO signingDTO, final File alfTempDir, final String alias, final KeyStore ks, final PrivateKey key, final Certificate[] chain) { final String fileNameToSign = fileFolderService.getFileInfo(nodeRefToSign).getName(); File fileConverted = null; File tempDir = null; try { ContentReader fileToSignContentReader = getReader(nodeRefToSign); if (fileToSignContentReader != null) { String newName = null; // Check if document is PDF or transform it if (!MimetypeMap.MIMETYPE_PDF.equals(fileToSignContentReader.getMimetype())) { // Transform document in PDF document final ContentTransformer tranformer = contentTransformerRegistry.getTransformer( fileToSignContentReader.getMimetype(), fileToSignContentReader.getSize(), MimetypeMap.MIMETYPE_PDF, new TransformationOptions()); if (tranformer != null) { tempDir = new File(alfTempDir.getPath() + File.separatorChar + nodeRefToSign.getId()); if (tempDir != null) { tempDir.mkdir(); fileConverted = new File(tempDir, fileNameToSign + "_" + System.currentTimeMillis() + ".pdf"); if (fileConverted != null) { final ContentWriter newDoc = new FileContentWriter(fileConverted); if (newDoc != null) { newDoc.setMimetype(MimetypeMap.MIMETYPE_PDF); tranformer.transform(fileToSignContentReader, newDoc); fileToSignContentReader = new FileContentReader(fileConverted); final String originalName = (String) nodeService.getProperty(nodeRefToSign, ContentModel.PROP_NAME); newName = originalName.substring(0, originalName.lastIndexOf(".")) + ".pdf"; } } } } else { log.error( "[" + fileNameToSign + "] No suitable converter found to convert the document in PDF."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] No suitable converter found to convert the document in PDF."); } } // Convert PDF in PDF/A format final File pdfAFile = convertPdfToPdfA(fileToSignContentReader.getContentInputStream()); final PdfReader reader = new PdfReader(new FileInputStream(pdfAFile)); if (nodeRefToSign != null) { tempDir = new File(alfTempDir.getPath() + File.separatorChar + nodeRefToSign.getId()); if (tempDir != null) { tempDir.mkdir(); final File file = new File(tempDir, fileNameToSign); if (file != null) { final FileOutputStream fout = new FileOutputStream(file); final PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0'); if (stp != null) { final PdfSignatureAppearance sap = stp.getSignatureAppearance(); if (sap != null) { sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED); sap.setReason(signingDTO.getSignReason()); sap.setLocation(signingDTO.getSignLocation()); sap.setContact(signingDTO.getSignContact()); sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED); sap.setImageScale(1); // digital signature if (signingDTO.getSigningField() != null && !signingDTO.getSigningField().trim().equalsIgnoreCase("")) { Image img = null; if (signingDTO.getImage() != null) { final ContentReader imageContentReader = getReader(signingDTO.getImage()); final AcroFields af = reader.getAcroFields(); if (af != null) { final List<FieldPosition> positions = af.getFieldPositions(signingDTO.getSigningField()); if (positions != null && positions.size() > 0 && positions.get(0) != null && positions.get(0).position != null) { final BufferedImage newImg = scaleImage( ImageIO.read(imageContentReader.getContentInputStream()), BufferedImage.TYPE_INT_RGB, Float.valueOf(positions.get(0).position.getWidth()).intValue(), Float.valueOf(positions.get(0).position.getHeight()).intValue()); img = Image.getInstance(newImg, null); } else { log.error( "[" + fileNameToSign + "] The field '" + signingDTO.getSigningField() + "' doesn't exist in the document."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] The field '" + signingDTO.getSigningField() + "' doesn't exist in the document."); } } if (img == null) { img = Image.getInstance( ImageIO.read(imageContentReader.getContentInputStream()), null); } sap.setImage(img); } sap.setVisibleSignature(signingDTO.getSigningField()); } else { int pageToSign = 1; if (DigitalSigningDTO.PAGE_LAST.equalsIgnoreCase( signingDTO.getPages().trim())) { pageToSign = reader.getNumberOfPages(); } else if (DigitalSigningDTO.PAGE_SPECIFIC.equalsIgnoreCase( signingDTO.getPages().trim())) { if (signingDTO.getPageNumber() > 0 && signingDTO.getPageNumber() <= reader.getNumberOfPages()) { pageToSign = signingDTO.getPageNumber(); } else { throw new AlfrescoRuntimeException("Page number is out of bound."); } } if (signingDTO.getImage() != null) { final ContentReader imageContentReader = getReader(signingDTO.getImage()); // Resize image final BufferedImage newImg = scaleImage( ImageIO.read(imageContentReader.getContentInputStream()), BufferedImage.TYPE_INT_RGB, signingDTO.getSignWidth(), signingDTO.getSignHeight()); final Image img = Image.getInstance(newImg, null); sap.setImage(img); } if (signingDTO.getPosition() != null && !DigitalSigningDTO.POSITION_CUSTOM.equalsIgnoreCase( signingDTO.getPosition().trim())) { final Rectangle pageRect = reader.getPageSizeWithRotation(1); sap.setVisibleSignature( positionSignature( signingDTO.getPosition(), pageRect, signingDTO.getSignWidth(), signingDTO.getSignHeight(), signingDTO.getxMargin(), signingDTO.getyMargin()), pageToSign, null); } else { sap.setVisibleSignature( new Rectangle( signingDTO.getLocationX(), signingDTO.getLocationY(), signingDTO.getLocationX() + signingDTO.getSignWidth(), signingDTO.getLocationY() - signingDTO.getSignHeight()), pageToSign, null); } } stp.close(); NodeRef destinationNode = null; NodeRef originalDoc = null; boolean addAsNewVersion = false; if (signingDTO.getDestinationFolder() == null) { destinationNode = nodeRefToSign; nodeService.addAspect(destinationNode, ContentModel.ASPECT_VERSIONABLE, null); addAsNewVersion = true; } else { originalDoc = nodeRefToSign; destinationNode = createDestinationNode( file.getName(), signingDTO.getDestinationFolder(), nodeRefToSign); } if (destinationNode != null) { final ContentWriter writer = contentService.getWriter(destinationNode, ContentModel.PROP_CONTENT, true); if (writer != null) { writer.setEncoding(fileToSignContentReader.getEncoding()); writer.setMimetype("application/pdf"); writer.putContent(file); file.delete(); if (fileConverted != null) { fileConverted.delete(); } nodeService.addAspect( destinationNode, SigningModel.ASPECT_SIGNED, new HashMap<QName, Serializable>()); nodeService.setProperty( destinationNode, SigningModel.PROP_REASON, signingDTO.getSignReason()); nodeService.setProperty( destinationNode, SigningModel.PROP_LOCATION, signingDTO.getSignLocation()); nodeService.setProperty( destinationNode, SigningModel.PROP_SIGNATUREDATE, new java.util.Date()); nodeService.setProperty( destinationNode, SigningModel.PROP_SIGNEDBY, AuthenticationUtil.getRunAsUser()); if (newName != null) { nodeService.setProperty(destinationNode, ContentModel.PROP_NAME, newName); } final X509Certificate c = (X509Certificate) ks.getCertificate(alias); nodeService.setProperty( destinationNode, SigningModel.PROP_VALIDITY, c.getNotAfter()); nodeService.setProperty( destinationNode, SigningModel.PROP_ORIGINAL_DOC, originalDoc); if (!addAsNewVersion) { if (!nodeService.hasAspect(originalDoc, SigningModel.ASPECT_ORIGINAL_DOC)) { nodeService.addAspect( originalDoc, SigningModel.ASPECT_ORIGINAL_DOC, new HashMap<QName, Serializable>()); } nodeService.createAssociation( originalDoc, destinationNode, SigningModel.PROP_RELATED_DOC); } } } else { log.error("[" + fileNameToSign + "] Destination node is not a valid NodeRef."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Destination node is not a valid NodeRef."); } } else { log.error("[" + fileNameToSign + "] Unable to get PDF appearance signature."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Unable to get PDF appearance signature."); } } else { log.error("[" + fileNameToSign + "] Unable to create PDF signature."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Unable to create PDF signature."); } } } } else { log.error("[" + fileNameToSign + "] Unable to get document to sign content."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] Unable to get document to sign content."); } if (pdfAFile != null) { pdfAFile.delete(); } return null; } else { log.error("[" + fileNameToSign + "] The document has no content."); return new AlfrescoRuntimeException( "[" + fileNameToSign + "] The document has no content."); } } catch (KeyStoreException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } catch (ContentIOException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } catch (IOException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } catch (DocumentException e) { log.error("[" + fileNameToSign + "] " + e); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + e.getMessage(), e); } finally { if (tempDir != null) { try { tempDir.delete(); } catch (Exception ex) { log.error("[" + fileNameToSign + "] " + ex); return new AlfrescoRuntimeException("[" + fileNameToSign + "] " + ex.getMessage(), ex); } } } }
/** * @param reader * @param writer * @param options * @throws Exception */ protected final void action( Action ruleAction, NodeRef actionedUponNodeRef, ContentReader reader, Map<String, Object> options) { PDDocument pdf = null; InputStream is = null; File tempDir = null; ContentWriter writer = null; try { // Get the split frequency int splitFrequency = 0; String splitFrequencyString = options.get(PARAM_SPLIT_AT_PAGE).toString(); if (!splitFrequencyString.equals("")) { try { splitFrequency = Integer.valueOf(splitFrequencyString); } catch (NumberFormatException e) { throw new AlfrescoRuntimeException(e.getMessage(), e); } } // Get contentReader inputStream is = reader.getContentInputStream(); // stream the document in pdf = PDDocument.load(is); // split the PDF and put the pages in a list Splitter splitter = new Splitter(); // Need to adjust the input value to get the split at the right page splitter.setSplitAtPage(splitFrequency - 1); // Split the pages List<PDDocument> pdfs = splitter.split(pdf); // Start page split numbering at int page = 1; // build a temp dir, name based on the ID of the noderef we are // importing File alfTempDir = TempFileProvider.getTempDir(); tempDir = new File(alfTempDir.getPath() + File.separatorChar + actionedUponNodeRef.getId()); tempDir.mkdir(); // FLAG: This is ugly.....get the first PDF. PDDocument firstPDF = (PDDocument) pdfs.remove(0); int pagesInFirstPDF = firstPDF.getNumberOfPages(); String lastPage = ""; String pg = "_pg"; if (pagesInFirstPDF > 1) { pg = "_pgs"; lastPage = "-" + pagesInFirstPDF; } String fileNameSansExt = getFilenameSansExt(actionedUponNodeRef, FILE_EXTENSION); firstPDF.save( tempDir + "" + File.separatorChar + fileNameSansExt + pg + page + lastPage + FILE_EXTENSION); try { firstPDF.close(); } catch (IOException e) { throw new AlfrescoRuntimeException(e.getMessage(), e); } // FLAG: Like I said: "_UGLY_" ..... and it gets worse PDDocument secondPDF = null; Iterator<PDDocument> its = pdfs.iterator(); int pagesInSecondPDF = 0; while (its.hasNext()) { if (secondPDF != null) { // Get the split document and save it into the temp dir with // new name PDDocument splitpdf = (PDDocument) its.next(); int pagesInThisPDF = splitpdf.getNumberOfPages(); pagesInSecondPDF = pagesInSecondPDF + pagesInThisPDF; PDFMergerUtility merger = new PDFMergerUtility(); merger.appendDocument(secondPDF, splitpdf); merger.mergeDocuments(); try { splitpdf.close(); } catch (IOException e) { throw new AlfrescoRuntimeException(e.getMessage(), e); } } else { secondPDF = (PDDocument) its.next(); pagesInSecondPDF = secondPDF.getNumberOfPages(); } } if (pagesInSecondPDF > 1) { pg = "_pgs"; lastPage = "-" + (pagesInSecondPDF + pagesInFirstPDF); } else { pg = "_pg"; lastPage = ""; } // This is where we should save the appended PDF // put together the name and save the PDF secondPDF.save( tempDir + "" + File.separatorChar + fileNameSansExt + pg + splitFrequency + lastPage + FILE_EXTENSION); for (File file : tempDir.listFiles()) { try { if (file.isFile()) { // Get a writer and prep it for putting it back into the // repo NodeRef destinationNode = createDestinationNode( file.getName(), (NodeRef) ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER), actionedUponNodeRef); writer = serviceRegistry .getContentService() .getWriter(destinationNode, ContentModel.PROP_CONTENT, true); writer.setEncoding(reader.getEncoding()); // original // encoding writer.setMimetype(FILE_MIMETYPE); // Put it in the repo writer.putContent(file); // Clean up file.delete(); } } catch (FileExistsException e) { throw new AlfrescoRuntimeException("Failed to process file.", e); } } } catch (COSVisitorException e) { throw new AlfrescoRuntimeException(e.getMessage(), e); } catch (IOException e) { throw new AlfrescoRuntimeException(e.getMessage(), e); } finally { if (pdf != null) { try { pdf.close(); } catch (IOException e) { throw new AlfrescoRuntimeException(e.getMessage(), e); } } if (is != null) { try { is.close(); } catch (IOException e) { throw new AlfrescoRuntimeException(e.getMessage(), e); } } if (tempDir != null) { tempDir.delete(); } } }