Tagging and Storing AEM Forms DoR in DAM

This article will walk through the use case of storing and tagging the DoR generated by AEM Forms in AEM DAM. The tagging of the document is done based on the submitted form data.

A common ask from customers is to store and tag the Document of Record(DoR) generated by AEM Forms in AEM DAM. The tagging of the document needs to be based on the Adaptive Forms’ submitted data. For example, if the employment status in the submitted data is “Retired”, we want to tag the document with “Retired” tag and store the document in DAM.

The use case is as follows:

  • A user fills out Adaptive Form. In the adaptive form, the user’s marital status(ex Single) and employment status (Ex Retired)is captured.
  • On form submission, an AEM Workflow is triggered. This workflow tags the document with the marital status(Single) and employment status(Retired) and stores the document in DAM.
  • Once the document is stored in DAM, the administrator should be able to search the document by these tags. For example search on Single or Retired would fetch the appropriate DoR’s.

To satisfy this use case a custom process step was written. In this step we fetch the values of the appropriate data elements from the submitted data. We then construct the tag tile using this value. For example if the value of marital status element is “Single”, the tag title becomes **Peak:EmploymentStatus/Single. **Using the TagManager API , we find the tag and apply the tag to the DoR.

The following is the complete code to Tag and store the Document of Record in AEM DAM.

package com.aemforms.setvalue.core;
import java.io.InputStream;
import javax.jcr.Node;
import javax.jcr.Session;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.metatype.annotations.Designate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import com.adobe.granite.workflow.WorkflowException;
import com.adobe.granite.workflow.WorkflowSession;
import com.adobe.granite.workflow.exec.WorkItem;
import com.adobe.granite.workflow.exec.WorkflowData;
import com.adobe.granite.workflow.exec.WorkflowProcess;
import com.adobe.granite.workflow.metadata.MetaDataMap;
import com.adobe.granite.workflow.model.WorkflowModel;
import com.day.cq.tagging.Tag;
import com.day.cq.tagging.TagManager;

@Component(property = {
   Constants.SERVICE_DESCRIPTION + "=Tag and Store Dor in DAM",
   Constants.SERVICE_VENDOR + "=Adobe Systems",
   "process.label" + "=Tag and Store Dor in DAM"
@Designate(ocd = TagDorServiceConfiguration.class)
public class TagAndStoreDoRinDAM implements WorkflowProcess
   private static final Logger log = LoggerFactory.getLogger(TagAndStoreDoRinDAM.class);

   private TagDorServiceConfiguration serviceConfig;
   public void activate(TagDorServiceConfiguration config)
      this.serviceConfig = config;
   public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap arg2) throws WorkflowException
       log.debug("The process arguments passed ..." + arg2.get("PROCESS_ARGS", "string").toString());
      String params = arg2.get("PROCESS_ARGS", "string").toString();
      WorkflowModel wfModel = workflowSession.getModel("/var/workflow/models/dam/update_asset");
      // Read the Tag DoR service configuration
      String damFolder = serviceConfig.damFolder();
      String dorPDFName = serviceConfig.dorPath();
      String dataXmlFile = serviceConfig.dataFilePath();
      log.debug("The Data Xml File is ..." + dataXmlFile + "DorPDFName" + dorPDFName);
      // Read the arguments passed to this workflow step
      String parameters[] = params.split(",");
      log.debug("The %%%% length of parameters is " + parameters.length);
      Tag[] tagArray = new Tag[parameters.length];
      WorkflowData wfData = workItem.getWorkflowData();
      String dorFileName = (String) wfData.getMetaDataMap().get("filename");
      log.debug("The dorFileName is ..." + dorFileName);
      String payloadPath = workItem.getWorkflowData().getPayload().toString();
      String dataFilePath = payloadPath + "/" + dataXmlFile + "/jcr:content";
      String dorDocumentPath = payloadPath + "/" + dorPDFName + "/jcr:content";
      log.debug("Data File Path" + dataFilePath);
      log.debug("Dor File Path" + dorDocumentPath);
      Session session = workflowSession.adaptTo(Session.class);
      ResourceResolver resourceResolver = workflowSession.adaptTo(ResourceResolver.class);
      com.day.cq.dam.api.AssetManager assetMgr = resourceResolver.adaptTo(com.day.cq.dam.api.AssetManager.class);
      DocumentBuilderFactory factory = null;
      DocumentBuilder builder = null;
      Document xmlDocument = null;
      Node xmlDataNode = null;
      Node dorDocumentNode = null;

         // create org.w3c.dom.Document object from submitted form data
         xmlDataNode = session.getNode(dataFilePath);
         log.debug("xml Data Node" + xmlDataNode.getName());
         dorDocumentNode = session.getNode(dorDocumentPath);
         log.debug("DOR Document Node is " + dorDocumentNode.getName());
         InputStream xmlDataStream = xmlDataNode.getProperty("jcr:data").getBinary().getStream();
         InputStream dorInputStream = dorDocumentNode.getProperty("jcr:data").getBinary().getStream();
         XPath xPath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
         factory = DocumentBuilderFactory.newInstance();
         builder = factory.newDocumentBuilder();
         xmlDocument = builder.parse(xmlDataStream);
         String newFile = "/content/dam/" + damFolder + "/" + dorFileName;
         log.debug("the new file is ..." + newFile);
         // Store the DoR in DAM
         assetMgr.createAsset(newFile, dorInputStream, "application/pdf", true);
         WorkflowData wfDataLoad = workflowSession.newWorkflowData("JCR_PATH", newFile);
         log.debug("Wrote the document to DAM" + newFile);
         TagManager tagManager = resourceResolver.adaptTo(TagManager.class);
         Resource pdfDocumentNode = resourceResolver.getResource(newFile);
         Resource metadata = pdfDocumentNode.getChild("jcr:content/metadata");
         // Fetch the xml elements from the xml document
         for (int i = 0; i < parameters.length; i++)
                String tagTitle = parameters[i].split("=")[0];
                log.debug("The tag title is" + tagTitle);
                String nameOfNode = parameters[i].split("=")[1];
                org.w3c.dom.Node xmlElement = (org.w3c.dom.Node) xPath.compile(nameOfNode).evaluate(xmlDocument, javax.xml.xpath.XPathConstants.NODE);
                log.debug("###The value data node is " + xmlElement.getTextContent());
                Tag tagFound = tagManager.resolveByTitle(tagTitle + xmlElement.getTextContent());
                log.debug("The tag found was ..." + tagFound.getPath());
                tagArray[i] = tagFound;
         tagManager.setTags(metadata, tagArray, true);
         workflowSession.startWorkflow(wfModel, wfDataLoad);
         log.debug("Workflow started");
         log.debug("Done setting tags");
      } catch (Exception e)
                 log.debug("The error message is " + e.getMessage());



To get this sample working on your system,Please follow the steps listed below:

  • Deploy the Developingwithserviceuser bundle

  • Download and deploy the setvalue bundle. This is the custom OSGI bundle which sets the tags from the submitted form data.

  • Download the sample adaptive form

  • Go to Forms And Documents

  • Click on Create | File Upload and upload the tag-and-store-in-dam-adaptive-form.zip

  • Import the article assets using AEM package manager

  • Open the sample form in preview mode. Fill in all the fields and submit the form.

  • Navigate to Peak folder in DAM. You should see DoR in the Peak folder. Check the properties of the document. It should be tagged appropriately.
    Congratulations!! You have successfully installed the sample on your system

  • Let’s explore the workflow which gets triggered on form submission.

  • The first step in the workflow creates a unique file name by concatenating applicants name and county of residence.

  • The second step of the workflow passes the tag hierarchy and the form fields elements that need to be tagged. The process step extracts the value from the submitted data and constructs the tag title that needs to tag the document.

  • If you want to store DoR in a different folder in the DAM, you specify the folder location using the configuration properties as specified in the screenshot below.

The other two parameters are specific to DoR and Data File Path as specified in the Adaptive Form submission options. Please make sure the values you specify here match with the values you specified in the Adaptive Form submission options.

Tag Dor

On this page