DoRServiceImpl.java 15.6 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  com.adobe.aemds.guide.addon.dor.DoRGenerationException
 *  com.adobe.aemds.guide.addon.dor.DoROptions
 *  com.adobe.aemds.guide.addon.dor.DoRResult
 *  com.adobe.aemds.guide.addon.dor.DoRService
 *  com.adobe.aemds.guide.service.GuideLocalizationService
 *  com.adobe.aemds.guide.service.GuideModelTransformer
 *  com.adobe.aemds.guide.service.XFAModelTransformer
 *  com.adobe.aemds.guide.utils.GuideModelUtils
 *  com.adobe.aemds.guide.utils.GuideUtils
 *  com.adobe.aemds.guide.utils.JSONCreationOptions
 *  com.adobe.aemds.guide.utils.XMLUtils
 *  com.adobe.aemfd.docmanager.Document
 *  com.adobe.fd.assembler.client.AssemblerOptionSpec
 *  com.adobe.fd.assembler.client.AssemblerResult
 *  com.adobe.fd.assembler.service.AssemblerService
 *  com.adobe.forms.common.service.FileAttachmentWrapper
 *  com.adobe.granite.i18n.LocaleUtil
 *  com.adobe.granite.resourceresolverhelper.ResourceResolverHelper
 *  org.apache.commons.io.IOUtils
 *  org.apache.commons.lang3.StringUtils
 *  org.apache.felix.scr.annotations.Component
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.ReferenceCardinality
 *  org.apache.felix.scr.annotations.ReferencePolicy
 *  org.apache.felix.scr.annotations.Service
 *  org.apache.sling.api.resource.Resource
 *  org.apache.sling.api.resource.ResourceResolver
 *  org.apache.sling.api.resource.ValueMap
 *  org.apache.sling.commons.json.JSONObject
 *  org.apache.sling.commons.json.xml.XML
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.aemds.guide.addon.dor.service.impl;

import com.adobe.aemds.guide.addon.dor.DoRGenerationException;
import com.adobe.aemds.guide.addon.dor.DoROptions;
import com.adobe.aemds.guide.addon.dor.DoRResult;
import com.adobe.aemds.guide.addon.dor.DoRService;
import com.adobe.aemds.guide.service.GuideLocalizationService;
import com.adobe.aemds.guide.service.GuideModelTransformer;
import com.adobe.aemds.guide.service.XFAModelTransformer;
import com.adobe.aemds.guide.utils.GuideModelUtils;
import com.adobe.aemds.guide.utils.GuideUtils;
import com.adobe.aemds.guide.utils.JSONCreationOptions;
import com.adobe.aemds.guide.utils.XMLUtils;
import com.adobe.aemfd.docmanager.Document;
import com.adobe.fd.assembler.client.AssemblerOptionSpec;
import com.adobe.fd.assembler.client.AssemblerResult;
import com.adobe.fd.assembler.service.AssemblerService;
import com.adobe.forms.common.service.FileAttachmentWrapper;
import com.adobe.granite.i18n.LocaleUtil;
import com.adobe.granite.resourceresolverhelper.ResourceResolverHelper;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.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.Service;
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.commons.json.JSONObject;
import org.apache.sling.commons.json.xml.XML;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Component(label="Document of Record Helper", description="Document of Record Helper Service", immediate=1)
@Service(value={DoRService.class})
public class DoRServiceImpl
implements DoRService {
    private static final Logger logger = LoggerFactory.getLogger(DoRServiceImpl.class);
    @Reference(policy=ReferencePolicy.DYNAMIC, cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    private GuideLocalizationService guideLocalizationService;
    @Reference(policy=ReferencePolicy.DYNAMIC, cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    private XFAModelTransformer xfaModelTransformerService;
    @Reference(policy=ReferencePolicy.DYNAMIC, cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    private GuideModelTransformer guideModelTransformer;
    @Reference(policy=ReferencePolicy.DYNAMIC, cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    public AssemblerService assemblerService;
    @Reference(policy=ReferencePolicy.DYNAMIC, cardinality=ReferenceCardinality.OPTIONAL_UNARY)
    public ResourceResolverHelper resourceResolverHelper;

    public DoRResult render(DoROptions options) throws DoRGenerationException {
        DoRResultImpl result;
        if (this.xfaModelTransformerService == null) {
            throw new DoRGenerationException("Unable to get the reference to the xfaModelTransformerService.");
        }
        Resource formResource = options.getFormResource();
        if (formResource == null) {
            throw new DoRGenerationException("Form Resource has not been assigned a Resource correctly.");
        }
        String afPath = formResource.getPath();
        if (afPath.endsWith("/")) {
            afPath = afPath.substring(0, afPath.length() - 1);
        }
        String xdpRef = null;
        String data = options.getData();
        String locale = options.getLocale().toString();
        HashSet<String> supportedLocales = new HashSet<String>();
        for (String lang : this.guideLocalizationService.getSupportedLocales()) {
            supportedLocales.add(LocaleUtil.parseLocale((String)lang).toString());
        }
        if (!supportedLocales.contains(locale)) {
            String language = options.getLocale().getLanguage();
            locale = supportedLocales.contains(language) ? language : "en";
        }
        if (!afPath.contains("/content/dam/formsanddocuments/") && !afPath.contains("/content/forms/af/")) {
            throw new DoRGenerationException("Adaptive Form is not found in the specified Path.");
        }
        if (!afPath.contains("/content/dam/formsanddocuments/")) {
            afPath = GuideUtils.convertGuideContainerPathToFMAssetPath((String)afPath);
        }
        Resource metaDataResource = formResource.getResourceResolver().getResource(afPath + "/jcr:content/metadata");
        ValueMap properties = metaDataResource.getValueMap();
        String guideContainerPath = GuideUtils.convertFMAssetPathToContainerPath((String)afPath);
        try {
            if (properties.get((Object)"formmodel").equals("jsonschema") || properties.get((Object)"formmodel").equals("formdatamodel")) {
                JSONObject dorCompliantJson = new JSONObject();
                JSONObject dataJson = new JSONObject(data);
                if (!dataJson.has("afData")) {
                    dorCompliantJson.put("data", (Object)dataJson);
                } else {
                    dorCompliantJson = dataJson;
                }
                data = XML.toString((Object)dorCompliantJson);
            }
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            XMLUtils.disableExternalEntities((DocumentBuilderFactory)dbf);
            DocumentBuilder db = dbf.newDocumentBuilder();
            org.w3c.dom.Document dataDoc = db.parse(new ByteArrayInputStream(data.getBytes("UTF-8")));
            org.w3c.dom.Document dorDoc = dbf.newDocumentBuilder().newDocument();
            Resource guideResource = formResource.getResourceResolver().getResource(guideContainerPath);
            JSONCreationOptions jsonCreationOptions = new JSONCreationOptions();
            jsonCreationOptions.setFormContainerPath(guideContainerPath);
            jsonCreationOptions.setIncludeFragmentJson(true);
            jsonCreationOptions.setLocale(new Locale(locale));
            JSONObject guideJSON = this.guideModelTransformer.exportGuideJsonObject(guideResource, jsonCreationOptions);
            String dorData = GuideModelUtils.getDataForDORMerge((org.w3c.dom.Document)dorDoc, (org.w3c.dom.Document)dataDoc, (JSONObject)guideJSON);
            if (GuideUtils.isDORConfigured((Resource)formResource)) {
                xdpRef = GuideUtils.getDoRTemplateRef((String)afPath, (String)locale, (ResourceResolver)formResource.getResourceResolver());
            }
            if (StringUtils.isEmpty((CharSequence)xdpRef)) {
                throw new DoRGenerationException("Document of record is not configured for given adaptive form" + afPath);
            }
            final String newxdpRef = xdpRef;
            final String newdorData = dorData;
            Map contentMap = (Map)this.resourceResolverHelper.callWith(formResource.getResourceResolver(), (Callable)new Callable<Map<String, Object>>(){

                @Override
                public Map<String, Object> call() throws Exception {
                    return DoRServiceImpl.this.xfaModelTransformerService.getPdfFromXfaDom(newxdpRef, newdorData);
                }
            });
            Document outputDoc = null;
            Document barePDF = null;
            if (contentMap == null) {
                throw new DoRGenerationException("Error during generation of document of record " + afPath);
            }
            result = new DoRResultImpl(new HashMap(contentMap));
            if (options.getIncludeAttachments()) {
                byte[] fileBytes = result.getContent();
                List attachments = options.getFileAttachments();
                barePDF = new Document((InputStream)new ByteArrayInputStream(fileBytes));
                if (attachments != null && attachments.size() > 0) {
                    outputDoc = this.addAttachmentsToPdf(xdpRef, barePDF, attachments);
                }
                if (outputDoc == null) {
                    outputDoc = barePDF;
                }
                InputStream pdfStream = outputDoc.getInputStream();
                byte[] attachmentPdf = IOUtils.toByteArray((InputStream)pdfStream);
                result.setOutputContent(attachmentPdf);
            }
        }
        catch (Exception e) {
            throw new DoRGenerationException("Error during document of record generation.", (Throwable)e);
        }
        return result;
    }

    private Document addAttachmentsToPdf(String formName, Document barePdf, List<FileAttachmentWrapper> attachments) throws DoRGenerationException {
        Document outputDoc = null;
        try {
            String ddxStart = "<DDX xmlns=\"http://ns.adobe.com/DDX/1.0/\">\n\t<PDF result=\"outDoc\">\n\t\t<PDF source=\"";
            String startTag1 = "<";
            String startTag2 = "</";
            String endTag2 = "/>";
            String endTag1 = ">";
            String FILE_ATTACHMENT = "FileAttachments";
            String FILE = "File";
            String quote = "\"";
            String ddxEnd = "\n\t" + startTag2 + "PDF" + endTag1 + "\n" + startTag2 + "DDX" + endTag1;
            String inputFilename = formName.replace(".xdp", ".pdf");
            StringBuilder ddx = new StringBuilder(ddxStart);
            ddx.append(inputFilename).append(quote).append(endTag2);
            HashMap<String, Document> inputMap = new HashMap<String, Document>();
            inputMap.put(inputFilename, barePdf);
            for (FileAttachmentWrapper attachment : attachments) {
                String fileName;
                String displayName = fileName.substring((fileName = attachment.getFileName()).lastIndexOf("%2F") != -1 ? fileName.lastIndexOf("%2F") + 3 : 0);
                displayName = displayName.substring(displayName.lastIndexOf("__afAttachment__") != -1 ? displayName.lastIndexOf("__afAttachment__") + 16 : 0);
                fileName = fileName.substring(fileName.indexOf("fileupload%2F") != -1 ? fileName.indexOf("fileupload%2F") + 13 : 0);
                ddx.append("\n\t\t").append(startTag1).append(FILE_ATTACHMENT).append(" source=\"").append(fileName).append(quote).append(" nameKey=" + quote).append(fileName).append(quote).append(endTag1);
                ddx.append("\n\t\t\t").append(startTag1).append(FILE).append(" filename=" + quote).append(displayName).append(quote).append(endTag2);
                ddx.append("\n\t\t").append(startTag2).append(FILE_ATTACHMENT).append(endTag1);
                inputMap.put(fileName, new Document(attachment.getInputStream()));
            }
            ddx.append(ddxEnd);
            Document ddxDoc = new Document(ddx.toString().getBytes("UTF-8"));
            AssemblerResult result = this.assemblerService.invoke(ddxDoc, inputMap, new AssemblerOptionSpec());
            outputDoc = (Document)result.getDocuments().get("outDoc");
            ddxDoc.dispose();
            for (Map.Entry me : inputMap.entrySet()) {
                if (inputFilename.equals(me.getKey())) continue;
                Document attachmentDoc = (Document)me.getValue();
                attachmentDoc.dispose();
            }
        }
        catch (Exception e) {
            throw new DoRGenerationException(e.getMessage(), (Throwable)e, true, true);
        }
        return outputDoc;
    }

    protected void bindGuideLocalizationService(GuideLocalizationService guideLocalizationService) {
        this.guideLocalizationService = guideLocalizationService;
    }

    protected void unbindGuideLocalizationService(GuideLocalizationService guideLocalizationService) {
        if (this.guideLocalizationService == guideLocalizationService) {
            this.guideLocalizationService = null;
        }
    }

    protected void bindXfaModelTransformerService(XFAModelTransformer xFAModelTransformer) {
        this.xfaModelTransformerService = xFAModelTransformer;
    }

    protected void unbindXfaModelTransformerService(XFAModelTransformer xFAModelTransformer) {
        if (this.xfaModelTransformerService == xFAModelTransformer) {
            this.xfaModelTransformerService = null;
        }
    }

    protected void bindGuideModelTransformer(GuideModelTransformer guideModelTransformer) {
        this.guideModelTransformer = guideModelTransformer;
    }

    protected void unbindGuideModelTransformer(GuideModelTransformer guideModelTransformer) {
        if (this.guideModelTransformer == guideModelTransformer) {
            this.guideModelTransformer = null;
        }
    }

    protected void bindAssemblerService(AssemblerService assemblerService) {
        this.assemblerService = assemblerService;
    }

    protected void unbindAssemblerService(AssemblerService assemblerService) {
        if (this.assemblerService == assemblerService) {
            this.assemblerService = null;
        }
    }

    protected void bindResourceResolverHelper(ResourceResolverHelper resourceResolverHelper) {
        this.resourceResolverHelper = resourceResolverHelper;
    }

    protected void unbindResourceResolverHelper(ResourceResolverHelper resourceResolverHelper) {
        if (this.resourceResolverHelper == resourceResolverHelper) {
            this.resourceResolverHelper = null;
        }
    }

    public final class DoRResultImpl
    implements DoRResult {
        public static final String OUTPUT_CONTENT = "outputContent";
        public static final String CONTENT_TYPE = "contentType";
        private Map<String, Object> contentMap;

        private DoRResultImpl(Map<String, Object> contentMap) {
            this.contentMap = contentMap;
        }

        public byte[] getContent() {
            return (byte[])this.contentMap.get("outputContent");
        }

        public String getContentType() {
            return (String)this.contentMap.get("contentType");
        }

        public Object getValue(String key) {
            return this.contentMap.get(key);
        }

        private void setOutputContent(byte[] pdfData) {
            this.contentMap.put("outputContent", pdfData);
        }
    }

}