Implement a Custom File Upload Preprocessor
Introduction
Goal
Implement custom preprocessing of images and assets uploaded by CMS users.
Background
CMS users can upload images and assets. In some cases it is desirable to preprocess such uploaded files before they are stored in the repository. For example, an organisation may want to sanitize certain metadata in uploaded PDF files before they are published on their public website.
To supports such use cases, developers can implement custom preprocessors in Java and configure them to be applied to uploaded files.
Instructions
Implement IUploadPreProcessor
Implement the interface org.hippoecm.frontend.plugins.yui.upload.model.IUploadPreProcessor in your project. The class should be deployed as part of the CMS application.
The method process provides an instance of org.hippoecm.frontend.plugins.yui.upload.model.UploadedFile which holds the file that is being uploaded. You can access and modify this file in your implementation of the process method:
public class MyFileUploadPreprocessor implements IUploadPreProcessor { private static final long serialVersionUID = 1L; @Override public void process(UploadedFile uploadedFile) { // implement preprocessing here } }
A full example is provided below in Example: Set PDF Author.
Configure the File Upload Preprocessor Service
Before you can configure your custom preprocessor, you must configure the preprocessor service in the JCR repository as follows:
/hippo:configuration/hippo:frontend/cms/cms-services/fileUploadPreProcessorService: jcr:primaryType: frontend:plugin plugin.class: org.hippoecm.frontend.plugins.yui.upload.processor.DefaultFileUploadPreProcessorPlugin pre.processor.id: service.upload.pre.processor /preProcessors: jcr:primaryType: frontend:pluginconfig
The configuration properties on the fileUploadPreProcessorService node are explained in more detail in the table below:
Property name | Property type | Description |
---|---|---|
plugin.class | String | The fully qualified classname of the service. This should normally always be org.hippoecm.frontend.plugins.yui.upload.processor.DefaultFileUploadPreProcessorPlugin. |
pre.processor.id | String | A unique ID identifying the service. The default value service.upload.pre.processor should normally not be changed unless you are configuring different preprocessor services for different types of uploads. |
The preProcessors node will act as parent node for the actual preprocessor configuration node(s) (see next section).
Configure the Preprocessor(s)
Below the preProcessors node (see previous section), configure your custom preprocessor as follows:
/hippo:configuration/hippo:frontend/cms/cms-services/fileUploadPreProcessorService/preProcessors/myfileuploadpreprocessor: jcr:primaryType: frontend:pluginconfig className: org.example.MyFileUploadPreprocessor
The configuration property on the fileUploadPreProcessorService node is explained in more detail in the table below:
Property name | Property type | Description |
---|---|---|
className | String | Fully qualified classname of a class implementing the IUploadPreProcessor interface. |
You can configure any number of preprocessor implementations by adding a configuration node for each.
Example: Set PDF Author
The AuthorFileUploadPreProcessor example preprocessor implementation below, which can also be found in the Bloomreach Experience Manager codebase, set the author meta field on any uploaded PDF document.
package org.hippoecm.frontend.plugins.yui.upload.preprocessors; import java.io.File; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocumentInformation; import org.hippoecm.frontend.plugins.yui.upload.model.IUploadPreProcessor; import org.hippoecm.frontend.plugins.yui.upload.model.UploadedFile; public class AuthorFileUploadPreProcessor implements IUploadPreProcessor { @Override public void process(final UploadedFile uploadedFile) { String mimeType = uploadedFile.getContentType(); PDDocument pdDocument = null; if(mimeType.equals("application/pdf")) { try { File file = uploadedFile.getFile(); pdDocument = PDDocument.load(file); PDDocumentInformation info = pdDocument.getDocumentInformation(); info.setAuthor("Processed by BRXM author"); pdDocument.save(file); } catch (IOException e) { // do nothing } finally { try { if (pdDocument != null) { pdDocument.close(); } } catch (IOException e) { // do nothing } } } } }
The full configuration for the above preprocessor would look as follows:
/hippo:configuration/hippo:frontend/cms/cms-services/fileUploadPreProcessorService: jcr:primaryType: frontend:plugin plugin.class: org.hippoecm.frontend.plugins.yui.upload.processor.DefaultFileUploadPreProcessorPlugin pre.processor.id: service.upload.pre.processor /preProcessors: jcr:primaryType: frontend:pluginconfig /pdf-author: jcr:primaryType: frontend:pluginconfig className: org.hippoecm.frontend.plugins.yui.upload.preprocessors.AuthorFileUploadPreProcessor
Configure Different Preprocessor Services for Different Types of Uploads
In the examples above, the configured preprocessors are applied to all uploaded files. It's also possible to configure a different preprocessor service for each of the following upload types:
- Iimages uploaded through the Images gallery folder tree in the Content application.
- Assets uploaded through the Assets gallery folder tree in the Content application.
- Images uploaded within the image picker for image fields and rich text fields in documents.
- Files uploaded to a embedded resource fields in documents.
The preprocessor service is configured similarly to the default preprocessor service but is linked to a specific upload type through a different, unique value of its pre.processor.id property.
For example:
/hippo:configuration/hippo:frontend/cms/cms-services/imagepreprocessorservice: jcr:primaryType: frontend:plugin plugin.class: org.hippoecm.frontend.plugins.yui.upload.processor.DefaultFileUploadPreProcessorPlugin pre.processor.id: image.preprocessor.id /preProcessors: jcr:primaryType: frontend:pluginconfig /image-preprocessor: jcr:primaryType: frontend:pluginconfig className: org.example.ImageUploadPreprocessor
Note the value of the pre.processor.id property is now "image.preprocessor.id". You can choose any string, as long as it's different from the default "service.upload.pre.processor" and from any other preprocessor service IDs already configured.
The actual preprocessors are configured as child nodes of the preProcessors node as before.
The final step is to link this particular preprocessor service to the desired upload types by adding a matching pre.processor.id property to the relevant configuration nodes from the list below:
- /hippo:configuration/hippo:workflows/gallery/image-gallery/frontend:renderer
For images uploaded through the Images gallery folder tree in the Content application. - /hippo:configuration/hippo:workflows/gallery/asset-gallery/frontend:renderer
For assets uploaded through the Assets gallery folder tree in the Content application. - /hippo:namespaces/hippogallerypicker/imagelink/editor:templates/_default_/root
For images uploaded within the image picker for image fields and rich text fields in documents. - /hippo:namespaces/hippo/resource/editor:templates/default/upload
For files uploaded to a embedded resource fields in documents.
For example, to apply this particular preprocessor service to image gallery uploads, add the pre.processor.id property with value "image.preprocessor.id" to /hippo:configuration/hippo:workflows/gallery/image-gallery/frontend:renderer:
/hippo:configuration/hippo:workflows/gallery/image-gallery/frontend:renderer: jcr:primaryType: frontend:plugin fileupload.maxItems: '25' gallery.processor.id: service.gallery.processor gallery.thumbnail.size: 60 option.label: add-image option.text: add-image-label plugin.class: org.hippoecm.frontend.plugins.gallery.GalleryWorkflowPlugin pre.processor.id: my.preprocessor.id validator.id: service.gallery.image.validation
Please note that:
- If an upload method has a pre.processor.id configured, only that preprocessor will be applied to files uploaded using that method.
- If an upload method has no pre.processor.id configured, only the default preprocessor (service.upload.pre.processor), will be applied to files uploaded using that method.