TemplateUnfolder.java 7.09 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.xfa.service.image;

import com.adobe.xfa.Attribute;
import com.adobe.xfa.Node;
import com.adobe.xfa.ProtoableNode;
import com.adobe.xfa.XFA;
import com.adobe.xfa.content.ImageValue;
import com.adobe.xfa.protocol.ProtocolUtils;
import com.adobe.xfa.template.TemplateModel;
import com.adobe.xfa.template.containers.Subform;
import com.adobe.xfa.ut.ExFull;
import com.adobe.xfa.ut.StringHolder;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;

public class TemplateUnfolder {
    private static final char[] charsToEncodeBeforePassingToURIClass = new char[]{' ', '\"', '<', '>', '[', '\\', ']', '^', '`', '{', '|', '}'};

    public static TemplateModel unfoldTemplate(TemplateModel oTemplate, String rootPath, EnumSet<TemplateUnfoldOptions> oTemplateUnfoldOptions) throws ExFull {
        try {
            assert (null != oTemplate);
            assert (null != rootPath);
            assert (null != oTemplateUnfoldOptions);
            if (null == oTemplate) {
                throw new ExFull(new NullPointerException("A null template is being passed. It should not be null."));
            }
            if (null == rootPath) {
                throw new ExFull(new NullPointerException("Root path is set to null. It should not be null."));
            }
            if (null == oTemplateUnfoldOptions) {
                throw new ExFull(new NullPointerException("Template Unfolding options are set to null. They should not be null."));
            }
            TemplateUnfolder.processNode(oTemplate, rootPath, oTemplateUnfoldOptions);
            return oTemplate;
        }
        catch (Exception e) {
            e.printStackTrace();
            ExFull ne = new ExFull(e);
            throw ne;
        }
    }

    private static String encodeForURIConsumption(String s) {
        s = s.replaceAll("\\\\", "/");
        char[] sortedArray = new char[charsToEncodeBeforePassingToURIClass.length];
        System.arraycopy(charsToEncodeBeforePassingToURIClass, 0, sortedArray, 0, sortedArray.length);
        Arrays.sort(sortedArray);
        StringBuffer b = new StringBuffer();
        for (int i = 0; i < s.length(); ++i) {
            char c = s.charAt(i);
            if (Arrays.binarySearch(sortedArray, c) >= 0) {
                if (c == '%') {
                    boolean dontProcessPercentage = false;
                    if (i + 2 < s.length() && s.charAt(1 + i) >= '0' && s.charAt(1 + i) <= '7' && (s.charAt(1 + i) >= '0' && s.charAt(1 + i) <= '9' || s.charAt(1 + i) >= 'a' && s.charAt(1 + i) <= 'f' || s.charAt(1 + i) >= 'A' && s.charAt(1 + i) <= 'F')) {
                        dontProcessPercentage = true;
                    }
                    if (dontProcessPercentage) {
                        b.append(c);
                        continue;
                    }
                    b.append(TemplateUnfolder.toHexString(c));
                    continue;
                }
                b.append(TemplateUnfolder.toHexString(c));
                continue;
            }
            b.append(c);
        }
        return b.toString();
    }

    private static void processNode(Node node, String parent, EnumSet<TemplateUnfoldOptions> oTemplateUnfoldOptions) throws Exception {
        ImageValue imageValue;
        boolean doIt;
        Attribute att;
        if (node instanceof ProtoableNode && (att = ((ProtoableNode)node).getAttributeByName("usehref", true)) != null && node instanceof Subform) {
            String sFragmentPath = att.getAttrValue();
            sFragmentPath = TemplateUnfolder.encodeForURIConsumption(sFragmentPath);
            boolean bl = doIt = oTemplateUnfoldOptions.contains((Object)TemplateUnfoldOptions.UNFOLD_ABSOLUTE_ASSETS) && ProtocolUtils.isAbsolute(sFragmentPath) || oTemplateUnfoldOptions.contains((Object)TemplateUnfoldOptions.UNFOLD_RELATIVE_ASSETS) && !ProtocolUtils.isAbsolute(sFragmentPath);
            if (doIt) {
                int lastFwdSlash = sFragmentPath.lastIndexOf(47);
                if (lastFwdSlash > -1) {
                    String fragmentUrl = sFragmentPath.substring(0, lastFwdSlash);
                    parent = ProtocolUtils.isAbsolute(fragmentUrl) ? fragmentUrl : parent + "/" + fragmentUrl;
                }
                ((Subform)node).removeAttr(null, "usehref");
            }
        }
        if (node instanceof ImageValue && (imageValue = (ImageValue)node).isPropertySpecified(XFA.HREFTAG, true, 0) && !imageValue.isPropertySpecified(XFA.TRANSFERENCODINGTAG, true, 0)) {
            String sHref = imageValue.getAttribute(XFA.HREFTAG).getAttrValue();
            sHref = TemplateUnfolder.encodeForURIConsumption(sHref);
            boolean bl = doIt = oTemplateUnfoldOptions.contains((Object)TemplateUnfoldOptions.UNFOLD_ABSOLUTE_ASSETS) && ProtocolUtils.isAbsolute(sHref) || oTemplateUnfoldOptions.contains((Object)TemplateUnfoldOptions.UNFOLD_RELATIVE_ASSETS) && !ProtocolUtils.isAbsolute(sHref);
            if (doIt) {
                String sContentType = imageValue.getAttribute(XFA.CONTENTTYPETAG).getAttrValue();
                if (!ProtocolUtils.isAbsolute(sHref)) {
                    while (parent.endsWith("/")) {
                        parent = parent.substring(0, parent.length() - 1);
                    }
                    sHref = parent + "/" + sHref;
                }
                String baseUrl = null;
                String relativeUrl = null;
                int idx = sHref.lastIndexOf("/");
                baseUrl = sHref.substring(0, idx);
                InputStream in = ProtocolUtils.checkUrl(baseUrl, relativeUrl = sHref.substring(1 + idx), true, new StringHolder());
                if (null == in) {
                    throw new IOException("Could not load image: " + sHref);
                }
                int sz = 1024;
                ArrayList<byte[]> list = new ArrayList<byte[]>();
                byte[] array = new byte[sz];
                int totalBytes = 0;
                int readSz = -1;
                while ((readSz = in.read(array)) > -1) {
                    byte[] clonedArray = new byte[readSz];
                    System.arraycopy(array, 0, clonedArray, 0, readSz);
                    list.add(clonedArray);
                    totalBytes += readSz;
                }
                byte[] finalArray = new byte[totalBytes];
                int sofar = 0;
                for (byte[] _t : list) {
                    System.arraycopy(_t, 0, finalArray, sofar, _t.length);
                    sofar += _t.length;
                }
                imageValue.setValue(finalArray, sContentType);
            }
        }
        for (Node child = node.getFirstXFAChild(); child != null; child = child.getNextXFASibling()) {
            TemplateUnfolder.processNode(child, parent, oTemplateUnfoldOptions);
        }
    }

    private static final String toHexString(char c) {
        String r = "%" + Integer.toHexString(c);
        return r;
    }

    public static enum TemplateUnfoldOptions {
        UNFOLD_RELATIVE_ASSETS,
        UNFOLD_ABSOLUTE_ASSETS;
        

        private TemplateUnfoldOptions() {
        }
    }

}