11-08-2017 05:14 AM
Hi all,
i need to create a Call-Web-Script DocLib action that execute a function based on java code.
The Java class get the input noderef, extract one its specific field and generate a pdf with only the field's value.
My difficult is generate and return a new pdf with custom content, i thought to use the java itext library.
Can someone help me?
Thank you.
11-08-2017 06:57 AM
Where specificly do you need help? You only mentioned what your task is, but not where you have any issues...
11-08-2017 09:37 AM
I need to add a new DocLib action to the Document Library of Alfresco Community 5.1 and i created a maven repo-amp and share-amp.
I followed this tutorial: http://docs.alfresco.com/5.0/tasks/dev-extensions-share-tutorials-add-action-doclib.html
In short, i executed these steps
1. In the share-amp, i added a new Surf Extension Module file "printProtocol-share-extensions.xml" that defines, for the "DocLibActions" condition, an action with id "print-protocol", a function called "onViewPrintableProtocol", the success message and failure messages for the action and finally defines the position of the action in the actionGroups tag. The file defines also a dependency for "DocLibCustom" condition that includes a "custom-doclib-actions.js" file.
2. In the share-amp, i added an icon for the action.
3. The JS file "custom-doclib-actions.js" implements the custom JavaScript function that registers a new custom action "onViewPrintablePDF", This action calls a custom Repository Web Script through the "printprotocol?noderef={myNodeRef}" url and sends to the webscript the noderef of the current node. The custom webscript must returns the pdf that has as content only the value of one specific field of the node.
5. In the repo-amp, i added a webscript "printProtocol" that returns a JSON result with the reference of the noderef of the node
5. In the repo-amp, i edited the java bean configuration file "webscript-context.xml" that links the webscript to the class java "protocolloPdfBean.java"
6. In the repo-amp, i implemented a java class "protocolloPdfBean" that gets the node and generate and return a pdf that has as content only the value of one specific field of the node.
I hope, that all is clear, thank you very much.
11-08-2017 10:49 AM
That looks like a good approach. Where are you stuck? Or, if you are seeing errors, what errors are you seeing?
11-09-2017 08:20 AM
My stuck was "in wich way write java code for generate a new pdf file", however i found a solution, this here is my code:
public NodeRef create(NodeRef currentNode, String protocolNumber){
ChildAssociationRef childAssociationRef = nodeService.getPrimaryParent(currentNode);
//get the parent of the current node
NodeRef parent = childAssociationRef.getParentRef();
//get the protocol field value
QName QNAME_FIELD_PRTOCOLO = QName.createQName("http://www.pyxisos.com/model/content/1.0", "protocollo_ap");
String protocollo = (String)nodeService.getProperty(currentNode, QNAME_FIELD_PRTOCOLO);
//create hashmap for nodeProtocol
Map<QName, Serializable> propsNodeProtocolo = new HashMap<QName, Serializable>(1);
//assign name prop_name
propsNodeProtocolo.put(ContentModel.PROP_NAME, "pdfTmp.pdf");
//create new node protocol
NodeRef nodeProtocol = nodeService.createNode(
parent,
ContentModel.ASSOC_CONTAINS,
QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "protocolloetichetta"),
ContentModel.TYPE_CONTENT,
propsNodeProtocolo
).getChildRef();
//set node MimetypeMap to MIMETYPE_PDF
ContentWriter writerNodeProtocol = this.contentService.getWriter(nodeProtocol, ContentModel.PROP_CONTENT, true);
writerNodeProtocol.setMimetype(MimetypeMap.MIMETYPE_PDF);
writerNodeProtocol.setEncoding("UTF-8");
writerNodeProtocol.putContent("TEST");
//create a pdf document
Rectangle pageSize = new Rectangle(200, 100);
Document document = new Document(pageSize);
try {
ContentWriter writer = contentService.getWriter(nodeProtocol, ContentModel.PROP_CONTENT, true);
PdfWriter.getInstance(document, writer.getContentOutputStream());
document.open();
//add the value of field protocol
document.add(new Paragraph(protocollo));
document.close();
} catch (Exception e) {
e.printStackTrace();
}
//return new pdf node
return nodeProtocol;
}
But now i have another stuck.
The real goal is click the "Print Protocol" action link of the node and open the printable pdf file that contains only the value of the "protocol field" of the node in a new tab window of the browser (to allow to print it). My code generates the real file PDF and save it in the same folder, but i don't want the physical file in that folder, thus i thought to call (always in the custom-doclib-actions.js file) a new custom webscript that delete the pdf node.
Could it be a a good solution?
Thank you.
11-13-2017 03:32 PM
Another idea would be to do this as a rendition. The PDF you are generating that shows only a single property value is really just an alternative rendition (another way to format) the original piece of content. Renditions get stored as children of the document so they are not visible or easily accessible from the UI by the end-user.
If you don't like the rendition idea you could just do what you are doing, but instead of storing the PDF in the same folder as the document, store it as a child of the document. This is basically what renditions do but you wouldn't have to formally configure it as an official rendition. It has the same benefit of not being easily accessible from the front-end by the end-user.
In both cases, it is nice that the PDF is a child of the document because if the document is ever deleted the child will also be deleted. This will prevent you from ending up with a bunch of PDFs hanging around after the original content has been deleted.
11-20-2017 05:14 AM
Ok, i like very much the rendition idea. In this way, i don't need to implement another web-service to delete the node pdf. I changed my code in this way.
Thank you very much.
public NodeRef create(NodeRef currentNode, String protocolNumber){
//get the protocol field value
QName QNAME_FIELD_PROTOCOLO = QName.createQName("http://www.pyxisos.com/model/content/1.0", "protocollo_ap");
String protocollo = (String)nodeService.getProperty(currentNode, QNAME_FIELD_PROTOCOLO);
//RENDITION OF THE INPUT NODE
//CREATE RENDITION DEFINITION
QName renditionName = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "myRendDefinition");
String renderingEngineName = ReformatRenderingEngine.NAME;
RenditionDefinition renditionDefinition = renditionService.createRenditionDefinition(renditionName, renderingEngineName);
renditionDefinition.setParameterValue(AbstractRenderingEngine.PARAM_MIME_TYPE, MimetypeMap.MIMETYPE_PDF);
//PERFORMING RENDITION
ChildAssociationRef renditionAssoc = renditionService.render(currentNode, renditionDefinition);
NodeRef nodeProtocol = renditionAssoc.getChildRef();
//WRITER OF NODE PROTOCOL
ContentWriter writerNodeProtocolo = this.contentService.getWriter(nodeProtocol, ContentModel.PROP_CONTENT, true);
writerNodeProtocolo.putContent("TEST");
//CREATE A PDF DOCUMENT FROM NODE PROTOCOL
Rectangle pageSize = new Rectangle(200, 100);
Document document = new Document(pageSize);
try {
ContentWriter writer = contentService.getWriter(nodeProtocol, ContentModel.PROP_CONTENT, true);
PdfWriter.getInstance(document, writer.getContentOutputStream());
document.open();
Font paragraphFont = FontFactory.getFont(FontFactory.HELVETICA, 10, Font.NORMAL);
//add the value of field protocol
document.add(new Paragraph("N. Protocollo: " + protocollo, paragraphFont));
document.setMargins(0, 0, 0, 0);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
//RETURN NODE PROTOCOL(RENDITION PDF FORMAT OF INPUT NODE)
return nodeProtocol;
}
Explore our Alfresco products with the links below. Use labels to filter content by product module.