Easy steps to create a custom workflow model in Adobe experience Manager (AEM) (PDF Watermarking)
Workflows are very important in any organization to channelize several given steps/tasks sequentially.
"Workflow is a set of independent or dependent tasks which are distinct and performed by a person or a group of people"
In Adobe Experience Manager (AEM) many operations and activities are automated using workflows. Workflows allow authors and business teams to perform tasks independently. This helps them to track, organize and control different processes without getting dependent on the technical team. Adobe Experience Manager (AEM) has many OOTB workflows to automate day-to-day tasks like publishing a page or an asset, creating a language copy, deleting videos or images, etc.
You might also like: See how Adobe Experience Manager can revolutionize your customer experience
Workflows can access assets (e.g. images, videos, documents), content pages, services, and resources in the AEM JCR repository. This makes workflows a perfect choice to perform complex tasks which involve interaction between different users and resources. AEM has a very strong framework to build and extend these workflows. This allows developers to quickly develop workflows specific to project requirements.
Let’s see how to create a custom workflow in AEM to “add watermark on PDF document".
We will cover the following topics to create the workflow:
- What is a workflow model?
- Create a custom workflow model
- What is a workflow process/step?
- Create a custom workflow process
- Add the process in a workflow model
What is a Workflow Model?
- A workflow model is a skeleton or a blueprint of the workflow consisting of sequential steps.
-
Process steps are defined either by a Java class or an ECMAScript.
- For the Java class processes, the fully qualified class name is provided.
- For the ECMAScript processes, the path to the script is provided.
- Every model has a start and end step.
- To initiate a workflow from the model, we need to select a payload which could be an asset or page which gets passed to each step as a string that is either a JCR path or a JCR identifier (UUID).
- Individual process steps that do act on the payload will usually expect a payload of a certain type, or act differently depending on the payload type.
Create a Custom Workflow Model
We will create a workflow to add a watermark to a PDF document.
Steps to create a workflow:
- Navigate to the Workflow Models console in AEM: AEM Start Page > Tools > Workflow > Models
So, here we will land on the Workflow Models console:
- Now to create the model, click on the “Create” button.
- Add the title for the workflow, in our case “Add PDF Watermark” and click on the “Done” button.
- You will get a workflow model created with the given title. To edit the steps, hover over the model and select it.
- Then click on the “Edit” button.
- It will take you to the Workflow Model editor. This is the default workflow model structure with a start and an end node also, with a default participant step. As we don’t require user participation for this workflow, we will delete it.
- Now we need to create a first step which will take a PDF document as a payload and the process adds the watermark based on the arguments configured in the model.
You might also like: How to implement OAuth SSO in Angular & Flask Application?
What is a Workflow Process/Step?
A workflow step component defines the appearance and behavior of the step when creating workflow models:
- The category and step name in the workflow sidekick
- The appearance of the step in the workflow models
- The edit dialog for configuring component properties
- The service or script that is executed at runtime
As with all components, workflow step components inherit from the component that is specified for the sling:resourceSuperType
property. The following diagram shows the hierarchy of cq:component
nodes that form the basis of all workflow step components. The diagram also includes the Process Step, Participant Step, and Dynamic Participant Step components, as these are the most common (and basic) starting points for developing custom step components.
Create a Custom Workflow Process
To create a workflow process/step we need to create the following structure:
- Workflow process component under
/apps/<project-name>/components/workflow
- JAVA class or ECMAScript to implement the process logic
First, we will create a Maven project with AEM archetype to add this structure.
Execute the following command to create a Maven AEM project with archetype version 19:
mvn -B archetype:generate -D archetypeGroupId=com.adobe.granite.archetypes -D archetypeArtifactId=aem-project-archetype -D archetypeVersion=19 -D groupId="com.hashout" -DartifactId="custom-workflow-step" -D artifactName="Custom Workflow Step" -D appsFolderName="custom-workflow-step" -D componentGroupName="Custom.Workflow.Step" -D siteName="Custom Workflow Step" -D optionAemVersion="6.4.4" -D optionIncludeErrorHandler="n" -D optionIncludeExamples="n"
Now we can create the required structure manually one by one but, we have a tool called YEOMAN. Yeoman is an open-source client-side scaffolding tool for web applications. Yeoman helps you to kickstart new projects, prescribing best practices and tools to help you stay productive.
With YEOMAN, we need to use a sub-generator to create the workflow process structure. One of the best sub-generators is generator-aem-application.
It supports the generation of the following modules:
- AEM components
- Clientlibs
- Custom Workflow Step
- Galen submodule
Note: Currently, it only supports JAVA class workflow process implementation.
Refer following steps to install YEOMAN and generator-aem-application:
- Download Node.js
-
Run following commands:
- npm install -g yo
- npm install -g generator-aem-application
To generate workflow process script and component structure, execute the following command and answer the questions as shown below:
C:\Custom Workflow Steps in AEM>yo aem-application:workflow
_-----_ ╭──────────────────────────╮
| | │ Welcome to the gnarly │
|--(o)--| │ generator-aem-applicatio │
`---------´ │ n:workflow generator! │
( _´U`_ ) ╰──────────────────────────╯
/___A___\ /
| ~ |
__'.___.'__
´ ` |° ´ Y `
? What's the name for the Workflow Process Step PDF Watermark
? What's the name for the component's maven module ui.apps
? What's the path for the component custom-workflow-step/components/workflow
? What's the name for the component's node pdf-watermark
? What's the name for the bundle's maven module core
? What's the name for the root package for the application com.hashout.core
? What's the relative name for the package for the workflow (without the root package) workflows
? What's the name for the Workflow process class PDFWatermarkProcess
It will create following files and copy these to the respective folders in your Maven project:
- ui.apps\src\main\content\jcrroot\apps\custom-workflow-step\components\workflow\pdf-watermark\cq_editConfig.xml
- ui.apps\src\main\content\jcrroot\apps\custom-workflow-step\components\workflow\pdf-watermark\cq_dialog.content.xml
- ui.apps\src\main\content\jcr_root\apps\custom-workflow-step\components\workflow\pdf-watermark.content.xml
- core\src\main\java\com\hashout\core\workflows\PDFWatermarkProcess.java
Each file has its role while rendering and processing the workflow process:
- .content.xml: Creates a
cq:Component
node withsling:resourceSuperType
as "cq/workflow/components/model/process" - cqeditConfig.xml: A node mentioning the process JAVA class and other options like
PROCESS_AUTO_ADVANCE
- cqdialog/.content.xml: Defines the process Touch UI dialog for workflow editor
PDFWatermarkProcess.java
: JAVA class entry point for processing of the payload passed in the workflow
From the above files, we need to edit the _cq_dialog/.content.xml
and add more fields as per the requirement.
You can download the cq:dialog file from here.
Now, we need to implement the JAVA class for the workflow process:
The execute
method of the WorkflowProcess
implementation is passed with the WorkItem
object. Use this object to obtain the WorkflowData
object for the current workflow instance. From this WorkflowData
object we will get the path of the PDF asset.
To get the asset binary, we need a Resource resolver object which we can adapt from the WorkflowSession
object.
The session passed to the WorkflowProcess
is backed by the service user for the workflow process service, which has the following permissions at the root of the repository:
• jcr:read
• rep:write
• jcr:versionManagement
• jcr:lockManagement
• crx:replicate
Also, to get arguments for the watermark, we need to use MetaDataMap
object.
@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) {
final WorkflowData workflowData = workItem.getWorkflowData();
final String type = workflowData.getPayloadType();
final String payloadPath = workflowData.getPayload().toString();
final ResourceResolver resolver = workflowSession.adaptTo(ResourceResolver.class);
final Resource assetResource = resolver != null ? resolver.getResource(payloadPath) : null;
final AssetManager assetManager = resolver != null ? resolver.adaptTo(AssetManager.class) : null;
// Check if the payload is under the DAM folder
if (StringUtils.equals(type, TYPE_JCR_PATH)
&& StringUtils.startsWith(payloadPath, DAM_ROOT_PATH)
&& assetResource != null
&& assetManager != null) {
//Adapt payload to asset
final Asset asset = assetResource.adaptTo(Asset.class);
if (asset != null && StringUtils.equals(asset.getMimeType(), PDF_MIMETYPE)) {
ByteArrayInputStream watermarkedPDFStream = applyWatermark(asset, args);
if (watermarkedPDFStream != null) {
assetManager.createAsset(payloadPath, watermarkedPDFStream, PDF_MIMETYPE, true);
}
}
}
}
To parse PDF documents and to add a watermark layer for each page, we will use the Apache PDFBox library. It is an open-source Java tool for working with PDF documents. It has the following features:
- Extract Unicode text from PDF files.
- Split a single PDF into many files or merge multiple PDF files.
- Extract data from PDF forms or fill a PDF form.
- Validate PDF files against the PDF/A-1b standard.
- Print a PDF file using the standard Java printing API.
- Save PDFs as image files, such as PNG or JPEG.
- Create a PDF from scratch, with embedded fonts and images.
- Digitally sign PDF files.
As the OSGi bundle for PDFBox is not available, we need to embed it with its dependencies in our project bundle. We can check the dependencies here.
Add PDFBox and its dependencies in the root POM:
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.23</version>
</dependency><dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>fontbox</artifactId>
<version>2.0.23</version>
</dependency><dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.60</version>
</dependency><dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.60</version>
</dependency>
Embed these dependencies in the project bundle by adding an embed configuration for bundle POM, core/pom.xml
.
Edit bundle build configuration and add the following configuration:
<Embed-Dependency>
pdfbox,
fontbox,
bcprov-jdk15on,
bcpkix-jdk15on
</Embed-Dependency>
Now, Add the code to process the PDF from PDFWatermarkProcess.java
.
Build the project and deploy it on AEM.
We have completed the development of the PDF Watermarking step and now we need to include it in the workflow model.
You might also like: Creating a Tool in Adobe Experience Manager
Using custom process with a workflow model
- To include the watermark process in the model, go to Workflow Editor again and search for the “PDF Watermark” process
- Add the process and click on the edit dialog button
- Add the watermark text and other configuration as shown below
- Click on the “Sync” button to store the changes
-
We also need to add the “Process Thumbnails” step to update the PDF thumbnail after adding the watermark. For that copy this step from the “DAM Update Asset” model as is shown below:
I. Open the “DAM Update Asset” in the editor
II. Click on the “Edit” button
III. Select the “Process Thumbnails” step and click on the copy button
IV. Open “Add PDF Watermark” in the editor and paste it in the
parsys
V. Click on the “Sync” button
- Congratulations, “Add PDF Watermark” workflow is ready to use!
- We can initiate this workflow from Assets or directly from the Workflow Models console
- We will get the following processed PDF:
Source Code
Download AEM Package
custom-workflow-step.ui.apps-1.0.zip
Conclusion
Adobe Experience Manager (AEM) workflows are very powerful to automate different tasks. Also, AEM’s workflow framework is extensive and easy to implement. We can create independent processes and use them across many workflows. This increases the reusability and efficiency.
References
PDFBox: https://pdfbox.apache.org/