@Override public NodeRef createNode( Resource resource, RepositoryLocation targetLocation, String encoding, String mimetype, QName nodeType) throws IOException { NodeRef rootNode = nodeService.getRootNode(targetLocation.getStoreRef()); final List<NodeRef> parentNodes = searchService.selectNodes( rootNode, targetLocation.getPath(), null, namespaceService, false); Assert.isTrue(parentNodes.size() == 1, "Target location leads to not 1 unique Node reference"); final String fileName = resource.getFilename(); final FileInfo fileInfo = fileFolderService.create(parentNodes.get(0), fileName, nodeType); final NodeRef nodeRef = fileInfo.getNodeRef(); final ContentWriter writer = contentService.getWriter(nodeRef, ContentModel.PROP_CONTENT, true); writer.putContent(resource.getInputStream()); if (mimetype == null) { mimetype = guessMimetype(resource); } if (encoding == null) { encoding = guessEncoding(resource.getInputStream(), mimetype); } writer.setMimetype(mimetype); writer.setEncoding(encoding); return nodeRef; }
/** * Write exception transfer report * * @return NodeRef the node ref of the new transfer report */ public NodeRef createTransferReport( Exception e, TransferTarget target, TransferDefinition definition, List<TransferEvent> events, File snapshotFile) { Map<QName, Serializable> properties = new HashMap<QName, Serializable>(); SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssSSSZ"); String timeNow = format.format(new Date()); String title = "Transfer report, error, " + timeNow; String description = "Transfer error report"; String name = "Transfer error report, " + timeNow; properties.put(ContentModel.PROP_NAME, name); properties.put(ContentModel.PROP_TITLE, title); properties.put(ContentModel.PROP_DESCRIPTION, description); ChildAssociationRef ref = nodeService.createNode( target.getNodeRef(), ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), TransferModel.TYPE_TRANSFER_REPORT, properties); ContentWriter writer = contentService.getWriter(ref.getChildRef(), ContentModel.PROP_CONTENT, true); writer.setLocale(Locale.getDefault()); writer.setMimetype(MimetypeMap.MIMETYPE_XML); writer.setEncoding(DEFAULT_ENCODING); // XMLTransferReportWriter reportWriter = new XMLTransferReportWriter(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(writer.getContentOutputStream())); try { reportWriter.startTransferReport(DEFAULT_ENCODING, bufferedWriter); // Header reportWriter.writeTarget(target); reportWriter.writeDefinition(definition); reportWriter.writeException(e); // Detail reportWriter.writeTransferEvents(events); reportWriter.endTransferReport(); return ref.getChildRef(); } catch (SAXException se) { return null; } finally { try { bufferedWriter.close(); } catch (IOException error) { error.printStackTrace(); } } }
/** * Create a new transfer report of success * * @return NodeRef the node ref of the new transfer report */ public NodeRef createTransferReport( Transfer transfer, TransferTarget target, TransferDefinition definition, List<TransferEvent> events, File snapshotFile) { Map<QName, Serializable> properties = new HashMap<QName, Serializable>(); SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssSSSZ"); String timeNow = format.format(new Date()); String title = "Transfer report, " + timeNow + "success"; String description = "Transfer report success targetName : " + target.getName(); String name = "Transfer report, " + timeNow; properties.put(ContentModel.PROP_NAME, name); properties.put(ContentModel.PROP_TITLE, title); properties.put(ContentModel.PROP_DESCRIPTION, description); ChildAssociationRef ref = nodeService.createNode( target.getNodeRef(), ContentModel.ASSOC_CONTAINS, QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, name), TransferModel.TYPE_TRANSFER_REPORT, properties); ContentWriter writer = contentService.getWriter(ref.getChildRef(), ContentModel.PROP_CONTENT, true); writer.setLocale(Locale.getDefault()); writer.setMimetype(MimetypeMap.MIMETYPE_XML); writer.setEncoding(DEFAULT_ENCODING); // final XMLTransferReportWriter reportWriter = new XMLTransferReportWriter(); BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(writer.getContentOutputStream())); try { reportWriter.startTransferReport(DEFAULT_ENCODING, bufferedWriter); // Header reportWriter.writeTarget(target); reportWriter.writeDefinition(definition); /** Write the node summary details to the transfer report */ TransferManifestProcessor processor = new TransferManifestProcessor() { public void processTransferManifestNode(TransferManifestNormalNode node) { try { reportWriter.writeNodeSummary(node); } catch (SAXException error) { error.printStackTrace(); } } public void processTransferManifestNode(TransferManifestDeletedNode node) { try { reportWriter.writeNodeSummary(node); } catch (SAXException error) { error.printStackTrace(); } } public void processTransferManifiestHeader(TransferManifestHeader header) { /* NO-OP */ } public void startTransferManifest() { /* NO-OP */ } public void endTransferManifest() { /* NO-OP */ } }; /** Step 3: wire up the manifest reader to a manifest processor */ SAXParserFactory saxParserFactory = SAXParserFactory.newInstance(); SAXParser parser; parser = saxParserFactory.newSAXParser(); XMLTransferManifestReader reader = new XMLTransferManifestReader(processor); /** Step 4: start the magic Give the manifest file to the manifest reader */ try { parser.parse(snapshotFile, reader); } catch (IOException error) { // TODO temp code error.printStackTrace(); return null; } // Detail Events reportWriter.writeTransferEvents(events); reportWriter.endTransferReport(); return ref.getChildRef(); } catch (SAXException se) { // TODO Temp code return null; } catch (ParserConfigurationException error) { // TODO temp code error.printStackTrace(); return null; } finally { try { bufferedWriter.close(); } catch (IOException error) { error.printStackTrace(); } } }
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); } } } }
@Override public void updateNode(Resource resource, NodeRef existingNode) throws IOException { contentService .getWriter(existingNode, ContentModel.PROP_CONTENT, true) .putContent(resource.getInputStream()); }