All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.adobe.fd.fp.common.FPSubmitHandler Maven / Gradle / Ivy

/*************************************************************************
*
* ADOBE CONFIDENTIAL
* ___________________
*
*  Copyright 2016 Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated and its
* suppliers and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
**************************************************************************/

package com.adobe.fd.fp.common;

import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.ReferencePolicy;
import org.apache.felix.scr.annotations.ReferencePolicyOption;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.adobe.aemds.guide.utils.GuideConstants;
import com.adobe.fd.fp.config.FormsPortalDraftsandSubmissionConfigService;
import com.adobe.fd.fp.exception.ErrorMessages;
import com.adobe.fd.fp.exception.FormsPortalException;
import com.adobe.fd.fp.model.SubmittedMetadata;
import com.adobe.fd.fp.service.FormsPortalPDFRenderService;
import com.adobe.fd.fp.service.SubmitDataService;
import com.adobe.fd.fp.service.SubmitMetadataService;
import com.adobe.fd.fp.service.SubmittedAFDataService;
import com.adobe.fd.fp.util.FormsPortalConstants;
import com.adobe.fd.fp.util.PortalUtils;
import com.adobe.fd.fp.util.PropertyUtils;
import com.adobe.fd.fp.util.RepositoryUtils;
import com.adobe.forms.common.service.FileAttachmentWrapper;

/**
 * @author sharoon
 *
 */
@SuppressWarnings("deprecation")
@Component
public abstract class FPSubmitHandler extends SlingAllMethodsServlet {

	/**
	 * Serial Version UID
	 */
	private static final long serialVersionUID = 3269969870036990497L;
	
	@Reference
	protected FormsPortalDraftsandSubmissionConfigService draftsandSubmissionConfiguration;
	
	@Reference(policy=ReferencePolicy.DYNAMIC, policyOption=ReferencePolicyOption.GREEDY, cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    protected FormsPortalPDFRenderService fpPdfRenderService;

	@Reference(policy=ReferencePolicy.DYNAMIC, policyOption=ReferencePolicyOption.GREEDY, cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    protected SubmittedAFDataService fpSubmittedAFUserDataService;
	
	@Reference
    protected PortalUtilsComponent portalUtilsComponent;

	private final Logger log = LoggerFactory.getLogger(FPSubmitHandler.class);
	
	@SuppressWarnings("unchecked")
	protected JSONObject submitForm(Map options, Node formNode) throws FormsPortalException{
		if (options == null || formNode == null) {
			throw new FormsPortalException(ErrorMessages.ALC_FMP_001_048);
		}
		try {
			Map metadataParams = new HashMap(); 
			String formType = options.containsKey(FormsPortalConstants.STR_FORM_TYPE) && options.get(FormsPortalConstants.STR_FORM_TYPE) != null ? 
					options.get(FormsPortalConstants.STR_FORM_TYPE).toString() :  FormsPortalConstants.STR_ADAPTIVE_FORM;
			String formData = options.get(FormsPortalConstants.STR_FORM_DATA) != null ? options.get(FormsPortalConstants.STR_FORM_DATA).toString() : null;
			byte[] dorBytes = (byte[])options.get(FormsPortalConstants.STR_PDF);
			
			//Populate the common properties
			metadataParams.put(FormsPortalConstants.STR_FORM_TYPE, formType != null? formType : "");
			metadataParams.put(FormsPortalConstants.STR_NODE_TYPE, getNodeType());
			metadataParams.put(FormsPortalConstants.STR_OWNER, options.get(FormsPortalConstants.STR_OWNER));
			metadataParams.put(FormsPortalConstants.STR_FORM_CONTAINER_PATH, options.get(FormsPortalConstants.STR_FORM_CONTAINER_PATH));
			metadataParams.put(FormsPortalConstants.STR_FILE_ATTACHMENT_MAP, options.get(FormsPortalConstants.STR_FILE_ATTACHMENT_MAP));
			metadataParams.put(FormsPortalConstants.STR_RENDER_PATH, FormsPortalConstants.STR_PORTAL_RENDER_NODE);			
			metadataParams.put(FormsPortalConstants.STR_STATUS, getStatus());
			metadataParams.put(GuideConstants.SUBMIT_TYPE, options.get(GuideConstants.SUBMIT_TYPE));
			String contentType = (String) options.get(FormsPortalConstants.STR_CONTENT_TYPE);
			//use xml as default datatType
			String dataType = null;
			if(StringUtils.isNotEmpty(contentType)) {
				if(contentType.equals(GuideConstants.CONTENT_TYPE_APPLICATION_JSON)) {
					dataType = FormsPortalConstants.STR_JSON;
				} else if(contentType.equals(GuideConstants.CONTENT_TYPE_APPLICATION_XML)) {
					dataType = FormsPortalConstants.STR_XML;
				} else {
					throw new FormsPortalException(ErrorMessages.ALC_FMP_001_049);
				}
			} else {
				throw new FormsPortalException(ErrorMessages.ALC_FMP_001_050);
			}
			metadataParams.put(FormsPortalConstants.STR_DATA_TYPE, dataType);
			filterAllowedMetadata(options, metadataParams);
			processAttachments((List)options.get(FormsPortalConstants.STR_ATTACHMENTS), metadataParams);
			// CQ-4230643 updated submission_info to af_submission_info as in case of other submission action, FPSubmitHandler is directly called with af_submission_info as parameter, so making it consistent across places.
			processComputedMetadata((String)options.get(FormsPortalConstants.STR_AF_SUBMISSION_INFO), metadataParams);
			boolean isDorAssociated = populateIndentification(formNode, formType, metadataParams);
			saveUserData(formData, formType, metadataParams);
			String locale = (String) options.get(FormsPortalConstants.STR_LOCALE);
			saveDor(isDorAssociated, dorBytes , formNode, formData, metadataParams, locale, (List)options.get(FormsPortalConstants.STR_ATTACHMENTS));
			saveAgreementData(options, metadataParams, formType);
			

			if(isDorAssociated){
				metadataParams.put(FormsPortalConstants.STR_SLING_RESOURCE_TYPE, FormsPortalConstants.STR_FD_FP_COMP_OPEN_SUBMITTED_GUIDE_XFA);
			} else {
	            metadataParams.put(FormsPortalConstants.STR_SLING_RESOURCE_TYPE, FormsPortalConstants.STR_FD_FP_COMP_OPEN_SUBMITTED_GUIDE_NON_XFA);
	            metadataParams.put(FormsPortalConstants.STR_SHOW_DOR_CLASS, FormsPortalConstants.STR_FP_DISPLAY_NONE);			
			}
			
			Date lastModified = new Date();
	        metadataParams.put(FormsPortalConstants.STR_JCR_LAST_MODIFIED, String.valueOf((lastModified).getTime()));
	        
	        if (FormsPortalConstants.STR_MOBILE_FORM.equals(formType)) {
				metadataParams.put(FormsPortalConstants.STR_XDP_REF, metadataParams.get(FormsPortalConstants.STR_FORM_PATH));
				metadataParams.put(FormsPortalConstants.STR_SUBMIT_URL, options.get(FormsPortalConstants.STR_SUBMIT_URL));
				metadataParams.put(FormsPortalConstants.STR_PROFILE, options.get(FormsPortalConstants.STR_PROFILE));
			} 
	        
	        return saveMetadata(metadataParams, Collections.singletonMap(FormsPortalConstants.STR_OWNER, options.get(FormsPortalConstants.STR_OWNER)));
		} catch (FormsPortalException e) {
			throw e;
		} catch (Exception e) {
			throw new FormsPortalException(e);
		}
	}

	private void saveAgreementData(Map options,
			Map metadataParams, String formType)
			throws Exception {
		if (options.containsKey(FormsPortalConstants.STR_AGREEMENT_DATA)) {
			String agreementData = (String)options.get(FormsPortalConstants.STR_AGREEMENT_DATA);
			metadataParams.put(FormsPortalConstants.STR_AGREEMENT_DATA_ID, saveData(agreementData.getBytes(), getSaveDataParams(agreementData, formType, metadataParams)));
			metadataParams.remove(FormsPortalConstants.STR_AGREEMENT_DATA);
		}
	}

	/** Helper method to filter the metadata parameters based on allowed metadata option in input.
	 * @param options Options received
	 * @param metadataParams metadata params to be saved
	 */
	protected void filterAllowedMetadata(Map options,
			Map metadataParams) {
		String fpAllowedMetadata = options
				.containsKey(FormsPortalConstants.STR_FP_ALLOWED_METADATA)
				&& options.get(FormsPortalConstants.STR_FP_ALLOWED_METADATA) != null ? options
				.get(FormsPortalConstants.STR_FP_ALLOWED_METADATA).toString()
				: "";
		if (options != null && metadataParams != null
				&& !StringUtils.isEmpty(fpAllowedMetadata)) {
			String[] fpAllowedMetadataArr = fpAllowedMetadata.split(",");
			for (String metadata : fpAllowedMetadataArr) {
				if (options.containsKey(metadata)) {
					metadataParams.put(metadata, options.get(metadata));
				}
			}
		}
	}
	
	/** Helper method to save attachments and add their respective properties in metadata
	 * @param attachments List of file attachments
	 * @param metadataParams metadata params
	 * @throws Exception 
	 */
	private void processAttachments(List attachments, Map metadataParams) throws Exception {
		if (attachments != null && metadataParams != null) {
			List attachmentKeyList = new ArrayList();
			Map saveOptions = Collections.singletonMap(FormsPortalConstants.STR_OWNER, metadataParams.get(FormsPortalConstants.STR_OWNER));
			for (FileAttachmentWrapper attachment : attachments) {
				String attachmentID = saveAttachment(IOUtils
						.toByteArray(attachment.getInputStream()), saveOptions);
				String attachmentKey = URLEncoder.encode(
						attachment.getFileName(), "UTF-8");
				metadataParams.put(attachmentKey, attachmentID);
				metadataParams.put(attachmentKey + "%2F"
						+ FormsPortalConstants.STR_CONTENT_TYPE,
						attachment.getContentType());
				attachmentKeyList.add(attachmentKey);
			}
			String[] attachmentKeys = new String[attachmentKeyList.size()];
			metadataParams.put(FormsPortalConstants.STR_ATTACHMENT_LIST,
					attachmentKeyList.toArray(attachmentKeys));
		}
		
	}
	
	/** Helper method to save the global computed metadata
	 * @param submissionInfo
	 * @param metadataParams
	 * @throws JSONException
	 */
	private void processComputedMetadata(String submissionInfo, Map metadataParams) throws JSONException {
		if (!StringUtils.isEmpty(submissionInfo) && metadataParams != null) {
			JSONObject submissionInfoJSON = new JSONObject(submissionInfo);
			if(submissionInfoJSON.has(FormsPortalConstants.STR_COMPUTED_META_INFO)){
				JSONObject computedMetadata = (JSONObject) submissionInfoJSON.get(FormsPortalConstants.STR_COMPUTED_META_INFO);
				Iterator computedMetaKeys = computedMetadata.keys();
    			while(computedMetaKeys.hasNext()){
    				String computedMetaKey = computedMetaKeys.next();
    				metadataParams.put(computedMetaKey, computedMetadata.get(computedMetaKey));
    			}
			}
		}
	}
	
	/** Helper method to populate identification details like name, form name, title, etc.
	 * @param formNode
	 * @param formType
	 * @param metadataParams
	 * @return whether dor is associated with this form or not
	 * @throws ValueFormatException
	 * @throws PathNotFoundException
	 * @throws RepositoryException
	 * @throws Exception
	 */
	private boolean populateIndentification(Node formNode, String formType, Map metadataParams) throws ValueFormatException, PathNotFoundException, RepositoryException, Exception {
		boolean isDorAssociated = false;
		if (formNode != null && !StringUtils.isEmpty(formType) && metadataParams != null) {
			RepositoryUtils repUtils     = RepositoryUtils.getInstance(draftsandSubmissionConfiguration);
			String formName = formNode.getName(), description = null;
			String formPath = formNode.getPath();
			if (formPath.startsWith(FormsPortalConstants.STR_CONTENT_DAM_FORMSANDDOCUMENTS)) {
			    //Metadata node will be present for assets managed by Forms Manager.
			    Node metadataNode = repUtils.getMetadataNode(formNode, false);
			    if (metadataNode.hasProperty(SubmittedMetadata.DESCRIPTION)) {
			        description = (String)PropertyUtils.getPropertyValue(metadataNode.getProperty(FormsPortalConstants.STR_DESCRIPTION));
			    }
				if (metadataNode.hasProperty(FormsPortalConstants.STR_TITLE) && !metadataNode.getProperty(FormsPortalConstants.STR_TITLE).getString().trim().isEmpty()) {
					formName = (String)PropertyUtils.getPropertyValue(metadataNode.getProperty(FormsPortalConstants.STR_TITLE));
				} else if(metadataNode.hasProperty(FormsPortalConstants.STR_NAME) && !metadataNode.getProperty(FormsPortalConstants.STR_NAME).getString().trim().isEmpty()){
					formName = (String)PropertyUtils.getPropertyValue(metadataNode.getProperty(FormsPortalConstants.STR_NAME));
				}

				//Check if a DOR is associated with this form.
				 isDorAssociated = PortalUtils.isDorAssociated(formType, metadataNode);
			} else {
				Node contentNode = repUtils.getContentNode(formNode, false);
				if (contentNode != null) {
				    if (contentNode.hasProperty(FormsPortalConstants.STR_JCR_DESCRIPTION)){
					    description = (String)PropertyUtils.getPropertyValue(contentNode.getProperty(FormsPortalConstants.STR_JCR_DESCRIPTION));
				    }
				    if (contentNode.hasProperty(FormsPortalConstants.STR_JCR_TITLE) && !contentNode.getProperty(FormsPortalConstants.STR_JCR_TITLE).getString().trim().isEmpty()){
					    formName = (String)PropertyUtils.getPropertyValue(contentNode.getProperty(FormsPortalConstants.STR_JCR_TITLE));
				    }
				}
			}
			metadataParams.put(FormsPortalConstants.STR_FORM_NAME, formName);
			metadataParams.put(FormsPortalConstants.STR_FORM_PATH, formPath);
			metadataParams.put(FormsPortalConstants.STR_DESCRIPTION, description);
			metadataParams.put(FormsPortalConstants.STR_NAME, formName);		//TODO have doubts on this.
		}
		return isDorAssociated;
	}
	
	/** Helper method to save user Data
	 * @param formData
	 * @param formType
	 * @param metadataParams
	 * @throws Exception 
	 */
	private void saveUserData(String formData, String formType, Map metadataParams) throws Exception {
		if (!StringUtils.isEmpty(formData) && !StringUtils.isEmpty(formType) && metadataParams != null) {
		    metadataParams.put(FormsPortalConstants.STR_USERDATA_ID, saveData(formData.getBytes(StandardCharsets.UTF_8), getSaveDataParams(formData, formType, metadataParams)));
		}
	}
	
	/** Helper method to save dor bytes if dor exists
	 * @param isDorAssociated
	 * @param dorBytes
	 * @param formNode
	 * @param formData
	 * @param metadataParams
	 * @throws Exception 
	 */
	protected void saveDor(boolean isDorAssociated, byte[] dorBytes, Node formNode, String formData, Map metadataParams, String locale, List attachments) throws Exception {
		if (isDorAssociated) {
			metadataParams.put(FormsPortalConstants.STR_SLING_RESOURCE_TYPE, FormsPortalConstants.STR_FD_FP_COMP_OPEN_SUBMITTED_GUIDE_XFA);
			if (dorBytes == null && fpPdfRenderService != null) {
				// CQ-4238476 - Forms submitted with attachments in them are not appearing in workflow with submit action "Invoke AEM Forms Workflow" & enable portal submit checked
				// Original references should not be updated, so copying the actual one and updating new one here.
				List attachmentWrappers = new ArrayList();
				for(FileAttachmentWrapper attachment: attachments) {
					FileAttachmentWrapper attachmentWrapper = new FileAttachmentWrapper(URLEncoder.encode(attachment.getFileName(), "UTF-8"), attachment.getContentType(), attachment.getValue());
					attachmentWrappers.add(attachmentWrapper);
				}
				dorBytes = fpPdfRenderService.getDorFromNode(formNode, formData.getBytes(), attachmentWrappers, locale);
			}
			if (dorBytes != null) {
				metadataParams.put(FormsPortalConstants.STR_DOR_ID, saveData(dorBytes, getSaveDataParams(formData, FormsPortalConstants.STR_ADAPTIVE_FORM, metadataParams)));
			} else {
				log.warn(ErrorMessages.ALC_FMP_001_054);
			}
		}
	}
	
	
	
	private Map getSaveDataParams(String formData, String formType, Map metadataParams) {
		 Map userdataParams = new HashMap();
	    userdataParams.put(FormsPortalConstants.STR_GUIDE_STATE, formData);
	    userdataParams.put(FormsPortalConstants.STR_GUIDE_NAME, (String)metadataParams.get(FormsPortalConstants.STR_FORM_NAME));
	    userdataParams.put(FormsPortalConstants.STR_USERDATA_ID, null);
	    userdataParams.put(FormsPortalConstants.STR_FORM_TYPE, formType);
	    userdataParams.put(FormsPortalConstants.STR_OWNER, metadataParams.get(FormsPortalConstants.STR_OWNER));
	    return userdataParams;
	}
	
	/** Helper method to save data
	 * @param formData
	 * @param options
	 * @return id of saved data
	 * @throws Exception 
	 */
	protected String saveData(byte[] formData, Map options) throws Exception {
		String userDataId = null;
		if (((String)options.get(FormsPortalConstants.STR_FORM_TYPE)).equals(FormsPortalConstants.STR_ADAPTIVE_FORM) &&
				fpSubmittedAFUserDataService != null) {
			userDataId = fpSubmittedAFUserDataService.submitAFUserData(options);
		} else {
			SubmitDataService fpSubmitDataService = (SubmitDataService) PortalUtils.getService(SubmitDataService.class, portalUtilsComponent.getSDSFilter());
			userDataId = fpSubmitDataService.saveData(null, formData);
		}
		return userDataId;
	}
	
	/** Helper method to save attachment
	 * @param attachment
	 * @param options 
	 * @return id of saved attachment
	 * @throws Exception 
	 */
	protected String saveAttachment(byte[] attachment, Map options) throws Exception {
		SubmitDataService fpSubmitDataService = (SubmitDataService) PortalUtils.getService(SubmitDataService.class, portalUtilsComponent.getSDSFilter());
		return fpSubmitDataService.saveAttachment(attachment);
	}
	
	/** Helper method to save metadata
	 * @param metadataProps
	 * @param saveOptions 
	 * @return saved metadata props
	 * @throws Exception 
	 */
	protected JSONObject saveMetadata(Map metadataProps, Map saveOptions) throws Exception {
		SubmitMetadataService fpSubmitMetadataService = (SubmitMetadataService) PortalUtils.getService(SubmitMetadataService.class, portalUtilsComponent.getSMSFilter());
		JSONObject result = fpSubmitMetadataService.submitMetadata(metadataProps);
		result.put(FormsPortalConstants.STR_PATH, FormsPortalConstants.STR_PORTAL_RENDER_NODE + ".dor.pdf/" + result.getString(FormsPortalConstants.STR_SUBMIT_ID));
		return result;
	}
	
	/** Helper method to get the status of this instance
	 * @return
	 */
	protected String getStatus() {
		return FormsPortalConstants.STR_SUBMITTED;
	}
	
	protected String getNodeType() {
		return FormsPortalConstants.STR_FP_SUBMITTED_FORM;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy