LCFormsSubmitActionServlet.java 18.7 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.forms.common.service.FileAttachmentWrapper
 *  com.adobe.forms.common.submitutils.CustomParameterRequest
 *  com.adobe.forms.common.submitutils.CustomResponse
 *  com.adobe.forms.common.submitutils.ParameterMap
 *  javax.servlet.RequestDispatcher
 *  javax.servlet.ServletException
 *  javax.servlet.ServletOutputStream
 *  javax.servlet.ServletRequest
 *  javax.servlet.ServletResponse
 *  org.apache.commons.io.IOUtils
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.ReferenceCardinality
 *  org.apache.felix.scr.annotations.ReferencePolicy
 *  org.apache.felix.scr.annotations.sling.SlingServlet
 *  org.apache.http.Header
 *  org.apache.http.HttpEntity
 *  org.apache.http.HttpResponse
 *  org.apache.http.StatusLine
 *  org.apache.http.client.methods.HttpPost
 *  org.apache.http.client.methods.HttpUriRequest
 *  org.apache.http.client.params.HttpClientParams
 *  org.apache.http.conn.ClientConnectionManager
 *  org.apache.http.entity.ByteArrayEntity
 *  org.apache.http.entity.ContentType
 *  org.apache.http.entity.mime.MultipartEntityBuilder
 *  org.apache.http.entity.mime.content.ByteArrayBody
 *  org.apache.http.entity.mime.content.ContentBody
 *  org.apache.http.impl.client.DefaultHttpClient
 *  org.apache.http.params.HttpParams
 *  org.apache.http.params.HttpProtocolParams
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestDispatcherOptions
 *  org.apache.sling.api.request.RequestParameter
 *  org.apache.sling.api.request.RequestParameterMap
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.api.servlets.SlingAllMethodsServlet
 *  org.apache.sling.commons.json.JSONObject
 *  org.apache.sling.commons.osgi.ServiceUtil
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.forms.web.servlets;

import com.adobe.forms.common.service.FileAttachmentWrapper;
import com.adobe.forms.common.submitutils.CustomParameterRequest;
import com.adobe.forms.common.submitutils.CustomResponse;
import com.adobe.forms.common.submitutils.ParameterMap;
import com.adobe.forms.external.service.FormSubmitPostProcessor;
import com.adobe.forms.service.LCFormsOptionService;
import com.adobe.forms.service.LCFormsService;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentSkipListMap;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
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.sling.SlingServlet;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.params.HttpClientParams;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.ContentBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestDispatcherOptions;
import org.apache.sling.api.request.RequestParameter;
import org.apache.sling.api.request.RequestParameterMap;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.commons.osgi.ServiceUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SlingServlet(paths={"/bin/xfaforms/submitaction"}, resourceTypes={"xfaforms/profile"}, methods={"HEAD", "POST"}, extensions={"submit.html"})
public class LCFormsSubmitActionServlet
extends SlingAllMethodsServlet {
    private static final HashSet<String> blacklistHeaders = new HashSet();
    private static final HashSet<String> blacklistResponseHeaders = new HashSet();
    Logger logger = LoggerFactory.getLogger(LCFormsSubmitActionServlet.class);
    @Reference
    private LCFormsOptionService lcFormsOptionService;
    @Reference
    private LCFormsService lcFormsService;
    @Reference(name="formSubmitPostProcessors", referenceInterface=FormSubmitPostProcessor.class, cardinality=ReferenceCardinality.OPTIONAL_MULTIPLE, policy=ReferencePolicy.DYNAMIC)
    private Map<Comparable<Object>, FormSubmitPostProcessor> formSubmitPostProcessors = new ConcurrentSkipListMap(Collections.reverseOrder());

    protected void doHead(SlingHttpServletRequest slingRequest, SlingHttpServletResponse response) throws ServletException, IOException {
        response.setStatus(200);
    }

    protected void doGet(SlingHttpServletRequest slingRequest, SlingHttpServletResponse response) throws ServletException, IOException {
        response.setStatus(200);
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    protected void doPost(SlingHttpServletRequest slingRequest, SlingHttpServletResponse response) throws ServletException, IOException {
        boolean bExecSubmitAction = false;
        boolean bExecValidate = this.lcFormsOptionService.get(slingRequest, "validate") != null;
        boolean execSubmitPostProcessor = this.lcFormsOptionService.get(slingRequest, "mfForceSubmitPostProcessing") != null;
        String contentRoot = this.lcFormsOptionService.get(slingRequest, "contentRoot");
        String template2 = this.lcFormsOptionService.get(slingRequest, "template");
        String mfDraftId = this.lcFormsOptionService.get(slingRequest, "mfDraftId");
        Boolean bRequestXml = "true".equals(this.lcFormsOptionService.get(slingRequest, "requestDataXml"));
        String submitUrl = this.getSubmitUrl(slingRequest, contentRoot, template2);
        String profile = this.lcFormsOptionService.get(slingRequest, "profile");
        boolean supportsAttachment = "true".equalsIgnoreCase(this.lcFormsOptionService.get(slingRequest, "mfAllowAttachments"));
        String dataXML = null;
        List<FileAttachmentWrapper> attachments = null;
        this.logger.debug("isValidate= " + bExecValidate);
        try {
            if (bExecValidate) {
                this.lcFormsOptionService.set(slingRequest, "scriptsToRun", "both");
            }
            this.lcFormsService.exportXFA(slingRequest);
            if ("form".equalsIgnoreCase(this.lcFormsOptionService.get(slingRequest, "packet"))) {
                response.setContentType("application/json; charset=UTF-8");
                response.getOutputStream().write(((String)slingRequest.getAttribute("mergedformdom")).getBytes("UTF-8"));
                execSubmitPostProcessor = false;
            } else if (bExecValidate) {
                response.setContentType("application/json; charset=UTF-8");
                response.getOutputStream().write(((String)slingRequest.getAttribute("submitResultJSON")).getBytes("UTF-8"));
                execSubmitPostProcessor = false;
            } else if (bRequestXml.booleanValue() || submitUrl == null || submitUrl.trim().isEmpty() || submitUrl.startsWith("mailto:")) {
                response.setContentType("application/xml; charset=UTF-8");
                dataXML = (String)slingRequest.getAttribute("mergedformdom");
                if (execSubmitPostProcessor && supportsAttachment) {
                    attachments = this.getAttachments(slingRequest, response);
                }
                response.getOutputStream().write(dataXML.getBytes("UTF-8"));
            } else {
                bExecSubmitAction = true;
            }
        }
        catch (Exception e) {
            this.log(e.getMessage(), (Throwable)e);
            response.setStatus(500);
        }
        if (bExecSubmitAction) {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpProtocolParams.setUserAgent((HttpParams)httpClient.getParams(), (String)slingRequest.getHeader("User-Agent"));
            HttpClientParams.setRedirecting((HttpParams)httpClient.getParams(), (boolean)true);
            HttpPost httpPost = new HttpPost(submitUrl);
            Enumeration headers = slingRequest.getHeaderNames();
            while (headers.hasMoreElements()) {
                String headerName = (String)headers.nextElement();
                if (blacklistHeaders.contains(headerName.toUpperCase())) continue;
                httpPost.setHeader(headerName, slingRequest.getHeader(headerName));
            }
            try {
                dataXML = (String)slingRequest.getAttribute("mergedformdom");
                if (!supportsAttachment) {
                    httpPost.setHeader("Content-Type", "application/xml");
                    httpPost.setEntity((HttpEntity)new ByteArrayEntity(dataXML.getBytes("UTF-8")));
                } else {
                    MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
                    multipartEntityBuilder.addTextBody("dataXml", dataXML);
                    attachments = this.getAttachments(slingRequest, response);
                    for (FileAttachmentWrapper attachment : attachments) {
                        byte[] fileAttachmentBytes = IOUtils.toByteArray((InputStream)attachment.getInputStream());
                        multipartEntityBuilder.addPart("attachments", (ContentBody)new ByteArrayBody(fileAttachmentBytes, ContentType.create((String)attachment.getContentType(), (Charset)Charset.forName("UTF-8")), attachment.getFileName()));
                    }
                    httpPost.setEntity(multipartEntityBuilder.build());
                }
                HttpResponse httpResponse = httpClient.execute((HttpUriRequest)httpPost);
                response.setStatus(httpResponse.getStatusLine().getStatusCode());
                for (Header respHeader : httpResponse.getAllHeaders()) {
                    String headerName = respHeader.getName();
                    if (blacklistResponseHeaders.contains(headerName.toUpperCase())) continue;
                    response.setHeader(headerName, respHeader.getValue());
                }
                HttpEntity respEntity = httpResponse.getEntity();
                Header contentType = respEntity.getContentType();
                if (contentType != null) {
                    response.setContentType(contentType.getValue());
                }
                respEntity.writeTo((OutputStream)response.getOutputStream());
                execSubmitPostProcessor = true;
            }
            catch (Exception e) {
                this.log("Couldn't post data to " + submitUrl, (Throwable)e);
                response.setStatus(500);
            }
            finally {
                httpClient.getConnectionManager().shutdown();
            }
        }
        if (execSubmitPostProcessor) {
            HashMap<String, String> optionsMap = new HashMap<String, String>();
            optionsMap.put("contentRoot", contentRoot);
            optionsMap.put("template", template2);
            optionsMap.put("mfDraftId", mfDraftId);
            optionsMap.put("profile", profile);
            optionsMap.put("submitUrl", submitUrl);
            for (FormSubmitPostProcessor formSubmitPostProcessor : this.formSubmitPostProcessors.values()) {
                try {
                    formSubmitPostProcessor.handlePostProcess(dataXML, attachments, optionsMap);
                }
                catch (Exception e) {
                    this.logger.error("The current formSubmitPostProcessor could not give path", (Throwable)e);
                }
            }
        }
    }

    private List<FileAttachmentWrapper> getAttachments(SlingHttpServletRequest slingRequest, SlingHttpServletResponse response) throws Exception {
        FileAttachmentWrapper fileAttachmentWrapper;
        ArrayList<FileAttachmentWrapper> attachments = new ArrayList<FileAttachmentWrapper>();
        String attachmentMapStr = this.lcFormsOptionService.get(slingRequest, "fileAttachmentMap");
        JSONObject attachJsonMap = new JSONObject(attachmentMapStr);
        Iterator iterator = attachJsonMap.keys();
        while (iterator.hasNext()) {
            String key2 = (String)iterator.next();
            String value = attachJsonMap.getString(key2);
            if (value.length() <= 0) continue;
            byte[] attachBytes = null;
            String fileName = null;
            String contentType = null;
            if (value.startsWith("/tmp/fd/xfaforms")) {
                Resource attachmentResource = slingRequest.getResourceResolver().getResource(value);
                Resource attachmentContentResource = attachmentResource.getChild("jcr:content");
                ValueMap attachmentContentMap = (ValueMap)attachmentContentResource.adaptTo(ValueMap.class);
                fileName = attachmentResource.getName();
                contentType = (String)attachmentContentMap.get("jcr:mimeType", (Object)"");
                attachBytes = IOUtils.toByteArray((InputStream)((InputStream)attachmentContentResource.adaptTo(InputStream.class)));
            } else {
                try {
                    ParameterMap newMap = new ParameterMap();
                    CustomParameterRequest newRequest = new CustomParameterRequest(slingRequest, newMap, "GET");
                    CustomResponse newResponse = new CustomResponse(response);
                    newRequest.getRequestDispatcher(value, new RequestDispatcherOptions()).forward((ServletRequest)newRequest, (ServletResponse)newResponse);
                    attachBytes = newResponse.getCopy();
                    fileName = key2;
                    contentType = newResponse.getContentType();
                }
                catch (Exception e) {
                    this.logger.error("[AEM]Error while hitting REST URL", (Throwable)e);
                }
            }
            fileAttachmentWrapper = new FileAttachmentWrapper(fileName, contentType, attachBytes);
            attachments.add(fileAttachmentWrapper);
        }
        for (Map.Entry param : slingRequest.getRequestParameterMap().entrySet()) {
            RequestParameter rp = ((RequestParameter[])param.getValue())[0];
            if (rp.isFormField()) continue;
            fileAttachmentWrapper = new FileAttachmentWrapper(rp.getFileName(), rp.getContentType(), rp.get());
            attachments.add(fileAttachmentWrapper);
        }
        return attachments;
    }

    private String getSubmitUrl(SlingHttpServletRequest slingRequest, String contentRoot, String template2) {
        String submitUrl = this.lcFormsOptionService.get(slingRequest, "submitUrl");
        String mfDisableSubmitUrlParameter = this.lcFormsOptionService.get(slingRequest, "mfDisableSubmitUrlParameter");
        String submitUrlParameter = slingRequest.getParameter("submitUrl");
        try {
            if (StringUtils.isBlank((CharSequence)submitUrl) || "true".equals(mfDisableSubmitUrlParameter) && submitUrl.equals(submitUrlParameter)) {
                submitUrl = this.getSubmitUrlFromFM(slingRequest, contentRoot, template2);
            }
        }
        catch (Exception e) {
            this.logger.error("could not find the submitUrl", (Throwable)e);
        }
        return submitUrl;
    }

    private String getSubmitUrlFromFM(SlingHttpServletRequest slingRequest, String contentRoot, String template2) {
        Resource formResource = null;
        Resource resource = null;
        Resource metadataResource = null;
        String submitUrl = "";
        if (StringUtils.isNotBlank((CharSequence)contentRoot) && StringUtils.isNotBlank((CharSequence)template2)) {
            formResource = slingRequest.getResourceResolver().getResource(contentRoot.replace("crx://", "") + "/" + template2);
        }
        if (formResource != null && this.isXFAResource(resource = formResource.getChild("jcr:content")) && (metadataResource = resource.getChild("metadata")) != null) {
            ValueMap metadataProperties = (ValueMap)metadataResource.adaptTo(ValueMap.class);
            submitUrl = (String)metadataProperties.get("submitUrl", (Object)"");
        }
        return submitUrl;
    }

    private boolean isXFAResource(Resource resource) {
        if (resource != null) {
            String resourceType = resource.getResourceType();
            return StringUtils.isNotBlank((CharSequence)resourceType) && resourceType.equals("fd/fm/xfaforms/render");
        }
        return false;
    }

    protected void bindFormSubmitPostProcessors(FormSubmitPostProcessor formSubmitPostProcessor, Map<String, Object> config) {
        this.formSubmitPostProcessors.put(ServiceUtil.getComparableForServiceRanking(config), formSubmitPostProcessor);
    }

    protected void unbindFormSubmitPostProcessors(FormSubmitPostProcessor formSubmitPostProcessor, Map<String, Object> config) {
        this.formSubmitPostProcessors.remove(ServiceUtil.getComparableForServiceRanking(config));
    }

    static {
        blacklistHeaders.add("CONTENT-LENGTH");
        blacklistHeaders.add("CONTENT-TYPE");
        blacklistResponseHeaders.add("TRANSFER-ENCODING");
        blacklistResponseHeaders.add("CONTENT-LENGTH");
    }

    protected void bindLcFormsOptionService(LCFormsOptionService lCFormsOptionService) {
        this.lcFormsOptionService = lCFormsOptionService;
    }

    protected void unbindLcFormsOptionService(LCFormsOptionService lCFormsOptionService) {
        if (this.lcFormsOptionService == lCFormsOptionService) {
            this.lcFormsOptionService = null;
        }
    }

    protected void bindLcFormsService(LCFormsService lCFormsService) {
        this.lcFormsService = lCFormsService;
    }

    protected void unbindLcFormsService(LCFormsService lCFormsService) {
        if (this.lcFormsService == lCFormsService) {
            this.lcFormsService = null;
        }
    }
}