Skip to content

Commit 1aba501

Browse files
author
Nathan McMinn
committed
PDF/A conversion action
First working version of PDF/A conversion action
1 parent dd35723 commit 1aba501

File tree

7 files changed

+160
-28
lines changed

7 files changed

+160
-28
lines changed

alfresco/src/main/properties/local/alfresco-global.properties

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,18 @@ ldap.synchronisation.import.group.cron=0 45 21 * * ?
306306
# - setting this to true means old group definitions will be tidied up.
307307
ldap.synchronisation.import.group.clearAllChildren=false
308308

309+
310+
311+
### External executable locations ###
312+
ooo.exe=/Users/nmcminn/Documents/Alfresco/enterprise-4.2.1.5/libreoffice.app/Contents/MacOS/soffice.bin
313+
ooo.enabled=false
314+
ooo.port=8100
315+
img.root=/Users/nmcminn/Documents/Alfresco/enterprise-4.2.1.5/common
316+
img.dyn=${img.root}/lib
317+
img.exe=${img.root}/bin/convert
318+
swf.exe=/Users/nmcminn/Documents/Alfresco/enterprise-4.2.1.5/common/bin/pdf2swf
319+
swf.languagedir=/Users/nmcminn/Documents/Alfresco/enterprise-4.2.1.5/common/japanese
320+
321+
jodconverter.enabled=true
322+
jodconverter.officeHome=/Users/nmcminn/Documents/Alfresco/enterprise-4.2.1.5/libreoffice.app/Contents
323+
jodconverter.portNumbers=8100

pdf-toolkit-repo/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@
3131
<groupId>org.alfresco</groupId>
3232
<artifactId>alfresco-repository</artifactId>
3333
</dependency>
34+
<dependency>
35+
<groupId>org.alfresco</groupId>
36+
<artifactId>alfresco-enterprise-repository</artifactId>
37+
<version>${alfresco.version}</version>
38+
<scope>compile</scope>
39+
</dependency>
3440
<dependency>
3541
<groupId>org.alfresco</groupId>
3642
<artifactId>alfresco-web-client</artifactId>

pdf-toolkit-repo/src/main/amp/config/alfresco/messages/pdf-toolkit.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,4 +164,4 @@ pdf-convert-to-archivable.title=Convert to PDF/A
164164
pdf-convert-to-archivable.description=Convert a PDF document to a PDF/A archive format
165165
pdf-convert-to-archivable.destination-folder.display-label=Destination folder
166166
pdf-convert-to-archivable.inplace.display-label=Execute in place
167-
pdf-convert-to-archivable.archive-level=PDF/A compliance level
167+
pdf-convert-to-archivable.archive-level.display-label=PDF/A compliance level

pdf-toolkit-repo/src/main/amp/config/alfresco/module/org.alfresco.extension.pdftoolkit/context/alfresco-pdf-toolkit-context.xml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,50 @@
180180
<property name="archiveLevelConstraint">
181181
<ref bean="pdfc-archivelevel"/>
182182
</property>
183+
<property name="jodConverter">
184+
<ref bean="jodconverter.shared.instance"/>
185+
</property>
183186
</bean>
184187

188+
<!-- Import the swftools transformer worker from the third party subsystem -->
189+
<bean id="jodconverter.shared.instance" class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory">
190+
<property name="sourceApplicationContextFactory">
191+
<ref bean="OOoJodconverter" />
192+
</property>
193+
<property name="sourceBeanName">
194+
<value>jodconverter.shared.instance</value>
195+
</property>
196+
<property name="interfaces">
197+
<list>
198+
<value>org.alfresco.enterprise.repo.content.JodConverter</value>
199+
</list>
200+
</property>
201+
</bean>
202+
203+
<!--<bean id="pdftoolkit-jod" class="org.alfresco.enterprise.repo.content.JodConverterSharedInstance">
204+
<property name="officeHome">
205+
<value>${jodconverter.officeHome}</value>
206+
</property>
207+
<property name="maxTasksPerProcess">
208+
<value>${jodconverter.maxTasksPerProcess}</value>
209+
</property>
210+
<property name="taskExecutionTimeout">
211+
<value>${jodconverter.taskExecutionTimeout}</value>
212+
</property>
213+
<property name="taskQueueTimeout">
214+
<value>${jodconverter.taskQueueTimeout}</value>
215+
</property>
216+
<property name="portNumbers">
217+
<value>${jodconverter.portNumbers}</value>
218+
</property>
219+
<property name="templateProfileDir">
220+
<value>${jodconverter.templateProfileDir}</value>
221+
</property>
222+
<property name="enabled">
223+
<value>${jodconverter.enabled}</value>
224+
</property>
225+
</bean>-->
226+
185227
<!-- Page count web script -->
186228
<bean id="webscript.org.alfresco.extension.pdftoolkit.pagecount.get" class="org.alfresco.extension.pdftoolkit.webscripts.GetPageCount" parent="webscript">
187229
<property name="ServiceRegistry" ref="ServiceRegistry"/>

pdf-toolkit-repo/src/main/java/org/alfresco/extension/pdftoolkit/repo/action/executer/BasePDFActionExecuter.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.alfresco.extension.pdftoolkit.repo.action.executer;
2020

2121

22+
import java.io.File;
2223
import java.io.Serializable;
2324
import java.util.List;
2425

@@ -32,9 +33,10 @@
3233
import org.alfresco.service.cmr.model.FileInfo;
3334
import org.alfresco.service.cmr.model.FileNotFoundException;
3435
import org.alfresco.service.cmr.repository.ContentReader;
36+
import org.alfresco.service.cmr.repository.ContentService;
3537
import org.alfresco.service.cmr.repository.NodeRef;
36-
import org.alfresco.service.cmr.repository.NodeService;
3738
import org.alfresco.service.namespace.QName;
39+
import org.alfresco.util.TempFileProvider;
3840

3941

4042
public abstract class BasePDFActionExecuter
@@ -44,6 +46,8 @@ public abstract class BasePDFActionExecuter
4446

4547
protected static final String FILE_EXTENSION = ".pdf";
4648
protected static final String FILE_MIMETYPE = "application/pdf";
49+
protected static final String PDF = "pdf";
50+
4751
protected ServiceRegistry serviceRegistry;
4852
//Default number of map entries at creation
4953
protected static final int INITIAL_OPTIONS = 5;
@@ -153,4 +157,24 @@ protected int getInteger(Serializable val)
153157
return 0;
154158
}
155159
}
160+
161+
protected File getTempFile(NodeRef nodeRef)
162+
{
163+
File alfTempDir = TempFileProvider.getTempDir();
164+
File toolkitTempDir = new File(alfTempDir.getPath() + File.separatorChar + nodeRef.getId());
165+
toolkitTempDir.mkdir();
166+
File file = new File(toolkitTempDir, serviceRegistry.getFileFolderService().getFileInfo(nodeRef).getName());
167+
168+
return file;
169+
}
170+
171+
protected File nodeRefToTempFile(NodeRef nodeRef)
172+
{
173+
ContentService cs = serviceRegistry.getContentService();
174+
File tempFromFile = TempFileProvider.createTempFile("PDFAConverter-", nodeRef.getId()
175+
+ FILE_EXTENSION);
176+
ContentReader reader = cs.getReader(nodeRef, ContentModel.PROP_CONTENT);
177+
reader.getContent(tempFromFile);
178+
return tempFromFile;
179+
}
156180
}

pdf-toolkit-repo/src/main/java/org/alfresco/extension/pdftoolkit/repo/action/executer/PDFConvertToArchivableActionExecuter.java

Lines changed: 69 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,32 @@
11
package org.alfresco.extension.pdftoolkit.repo.action.executer;
22

3+
import java.io.File;
4+
import java.io.FileNotFoundException;
5+
import java.net.ConnectException;
36
import java.util.HashMap;
47
import java.util.List;
58
import java.util.Map;
69

7-
import net.sf.jooreports.converter.DocumentFamily;
8-
import net.sf.jooreports.converter.DocumentFormat;
9-
10+
import org.alfresco.enterprise.repo.content.JodConverter;
11+
import org.alfresco.error.AlfrescoRuntimeException;
1012
import org.alfresco.extension.pdftoolkit.constraints.MapConstraint;
13+
import org.alfresco.model.ContentModel;
1114
import org.alfresco.repo.action.ParameterDefinitionImpl;
1215
import org.alfresco.service.cmr.action.Action;
1316
import org.alfresco.service.cmr.action.ParameterDefinition;
1417
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
18+
import org.alfresco.service.cmr.repository.ContentService;
19+
import org.alfresco.service.cmr.repository.ContentWriter;
1520
import org.alfresco.service.cmr.repository.NodeRef;
21+
import org.alfresco.service.cmr.repository.NodeService;
22+
import org.alfresco.util.SocketOpenOfficeConnection;
1623
import org.apache.commons.logging.Log;
1724
import org.apache.commons.logging.LogFactory;
25+
import org.artofsolving.jodconverter.OfficeDocumentConverter;
26+
import org.artofsolving.jodconverter.document.DefaultDocumentFormatRegistry;
27+
import org.artofsolving.jodconverter.document.DocumentFamily;
28+
import org.artofsolving.jodconverter.document.DocumentFormat;
29+
import org.artofsolving.jodconverter.document.DocumentFormatRegistry;
1830

1931
public class PDFConvertToArchivableActionExecuter extends BasePDFActionExecuter
2032
{
@@ -36,6 +48,10 @@ public class PDFConvertToArchivableActionExecuter extends BasePDFActionExecuter
3648
*/
3749
public static HashMap<String, String> archiveLevelConstraint = new HashMap<String, String>();
3850

51+
private final String PDFA = "PDF/A";
52+
53+
private JodConverter jodConverter;
54+
3955
/**
4056
* Add parameter definitions
4157
*/
@@ -52,26 +68,60 @@ protected void addParameterDefinitions(List<ParameterDefinition> paramList)
5268
protected void executeImpl(Action action, NodeRef actionedUponNodeRef)
5369
{
5470

55-
// get a connection to OpenOffice via the usual Alfresco means
71+
NodeService ns = serviceRegistry.getNodeService();
72+
ContentService cs = serviceRegistry.getContentService();
5673

57-
// create the right configuration for OpenOffice
74+
if(!ns.exists(actionedUponNodeRef))
75+
{
76+
throw new AlfrescoRuntimeException("PDF/A convert action called on non-existent node: " + actionedUponNodeRef);
77+
}
5878

79+
Boolean inplace = Boolean.valueOf(String.valueOf(action.getParameterValue(PARAM_INPLACE)));
80+
Integer archiveLevel = Integer.valueOf(String.valueOf(action.getParameterValue(PARAM_ARCHIVE_LEVEL)));
81+
82+
// get an output file for the new PDF (temp file)
83+
File out = getTempFile(actionedUponNodeRef);
84+
85+
// copy the source node content to a temp file
86+
File in = nodeRefToTempFile(actionedUponNodeRef);
87+
5988
// transform to PDF/A
89+
DocumentFormatRegistry formatRegistry = new DefaultDocumentFormatRegistry();
90+
formatRegistry.getFormatByExtension(PDF).setInputFamily(DocumentFamily.DRAWING);
91+
OfficeDocumentConverter converter = new OfficeDocumentConverter(jodConverter.getOfficeManager(), formatRegistry);
92+
93+
converter.convert(in, out, getDocumentFormat(archiveLevel));
94+
95+
NodeRef destinationNode = createDestinationNode(String.valueOf(ns.getProperty(actionedUponNodeRef, ContentModel.PROP_NAME)),
96+
(NodeRef)action.getParameterValue(PARAM_DESTINATION_FOLDER), actionedUponNodeRef, inplace);
97+
ContentWriter writer = serviceRegistry.getContentService().getWriter(destinationNode, ContentModel.PROP_CONTENT, true);
98+
writer.setEncoding(cs.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT).getEncoding());
99+
writer.setMimetype(FILE_MIMETYPE);
100+
writer.putContent(out);
101+
102+
// delete the temp files
103+
in.delete();
104+
out.delete();
60105

61106
}
62107

63108
/**
64-
* Returns DocumentFormat of PDF/A
109+
* Returns a DocumentFormat that will output to PDF/A
65110
*/
66-
/*private DocumentFormat toDocumentFormatPDFA(int level) {
111+
private DocumentFormat getDocumentFormat(int level) {
112+
113+
DocumentFormat format = new DocumentFormat(PDFA, PDF, FILE_MIMETYPE);
114+
Map<String, Object> properties = new HashMap<String, Object>();
115+
properties.put("FilterName", "draw_pdf_Export");
67116

68-
DocumentFormat customPdfFormat = new DocumentFormat(PORTABEL_FORMAT, PDF_APP, "pdf");
69-
customPdfFormat.setExportFilter(DocumentFamily.TEXT, "writer_pdf_Export");
70-
final Map<String, Integer> pdfOptions = new HashMap<String, Integer>();
71-
pdfOptions.put("SelectPdfVersion", level);
72-
customPdfFormat.setExportOption(DocumentFamily.TEXT, "FilterData", pdfOptions);
73-
return customPdfFormat;
74-
}*/
117+
Map<String, Object> filterData = new HashMap<String, Object>();
118+
filterData.put("SelectPdfVersion", level);
119+
properties.put("FilterData", filterData);
120+
121+
format.setStoreProperties(DocumentFamily.DRAWING, properties);
122+
123+
return format;
124+
}
75125

76126
/**
77127
* Setter for constraint bean
@@ -82,4 +132,9 @@ public void setArchiveLevelConstraint(MapConstraint mc)
82132
{
83133
archiveLevelConstraint.putAll(mc.getAllowableValues());
84134
}
135+
136+
public void setJodConverter(JodConverter jodConverter)
137+
{
138+
this.jodConverter = jodConverter;
139+
}
85140
}

pdf-toolkit-repo/src/main/java/org/alfresco/extension/pdftoolkit/repo/action/executer/PDFWatermarkActionExecuter.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -262,12 +262,7 @@ private void imageAction(Action ruleAction, NodeRef actionedUponNodeRef, NodeRef
262262

263263
try
264264
{
265-
// get a temp file to stash the watermarked PDF in before moving to
266-
// repo
267-
File alfTempDir = TempFileProvider.getTempDir();
268-
tempDir = new File(alfTempDir.getPath() + File.separatorChar + actionedUponNodeRef.getId());
269-
tempDir.mkdir();
270-
File file = new File(tempDir, serviceRegistry.getFileFolderService().getFileInfo(actionedUponNodeRef).getName());
265+
File file = getTempFile(actionedUponNodeRef);
271266

272267
// get the PDF input stream and create a reader for iText
273268
PdfReader reader = new PdfReader(actionedUponContentReader.getContentInputStream());
@@ -418,12 +413,7 @@ private void textAction(Action ruleAction, NodeRef actionedUponNodeRef, ContentR
418413

419414
try
420415
{
421-
// get a temp file to stash the watermarked PDF in before moving to
422-
// repo
423-
File alfTempDir = TempFileProvider.getTempDir();
424-
tempDir = new File(alfTempDir.getPath() + File.separatorChar + actionedUponNodeRef.getId());
425-
tempDir.mkdir();
426-
File file = new File(tempDir, serviceRegistry.getFileFolderService().getFileInfo(actionedUponNodeRef).getName());
416+
File file = getTempFile(actionedUponNodeRef);
427417

428418
// get the PDF input stream and create a reader for iText
429419
PdfReader reader = new PdfReader(actionedUponContentReader.getContentInputStream());

0 commit comments

Comments
 (0)