HrefStore.java 12.6 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.xfa.service.href;

import com.adobe.xfa.AppModel;
import com.adobe.xfa.Chars;
import com.adobe.xfa.Element;
import com.adobe.xfa.HrefHandler;
import com.adobe.xfa.LogMessenger;
import com.adobe.xfa.ModelFactory;
import com.adobe.xfa.Node;
import com.adobe.xfa.protocol.ProtocolUtils;
import com.adobe.xfa.service.href.HrefService;
import com.adobe.xfa.service.storage.PacketHandler;
import com.adobe.xfa.service.storage.XMLStorage;
import com.adobe.xfa.template.TemplateModelFactory;
import com.adobe.xfa.ut.ExFull;
import com.adobe.xfa.ut.MsgFormatPos;
import com.adobe.xfa.ut.ResId;
import com.adobe.xfa.ut.StringHolder;
import com.adobe.xfa.ut.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public final class HrefStore
implements PacketHandler {
    private static final String patentRef = "AdobePatentID=\"B624\"";
    private final Map<String, CacheItem> moHrefs;
    private String msContainerConfigBaseUrl;
    private String msImplicitBaseUrl;
    private String msBaseUrl;
    private String msAltUrl;
    private boolean mbTrusted;
    private int mnCacheIndex;
    private int mnCacheSize;
    private int mnCurrentCacheSize;
    private final HrefService moHrefService;

    HrefStore(HrefService oHrefService, String sBaseUrl, String sAltUrl, int nCacheSize) {
        this.moHrefService = oHrefService;
        this.moHrefs = new HashMap<String, CacheItem>();
        this.msBaseUrl = sBaseUrl;
        this.msAltUrl = sAltUrl;
        this.mbTrusted = true;
        this.mnCacheSize = nCacheSize;
    }

    void add(String sUrl) {
        String sBaseUrl = this.getImplicitBaseUrl();
        File oFile = new File(sUrl);
        String sFullUrl = null;
        sFullUrl = oFile.isAbsolute() ? sUrl : (sBaseUrl != null ? sBaseUrl + sUrl : sUrl);
        CacheItem oItem = this.moHrefs.get(sFullUrl);
        if (oItem == null) {
            this.moHrefs.put(sFullUrl, new CacheItem());
        }
    }

    void remove(String sUrl) {
        String sBaseUrl = this.getImplicitBaseUrl();
        File oFile = new File(sUrl);
        String sFullUrl = null;
        sFullUrl = oFile.isAbsolute() ? sUrl : (sBaseUrl != null ? sBaseUrl + sUrl : sUrl);
        CacheItem oItem = this.moHrefs.get(sFullUrl);
        if (oItem.mnCacheIndex >= 0) {
            this.mnCurrentCacheSize -= oItem.mnSize;
        }
        this.moHrefs.remove(sFullUrl);
    }

    private CacheItem get(String sUrl) {
        String sBaseUrl = this.getImplicitBaseUrl();
        File oFile = new File(sUrl);
        String sFullUrl = null;
        sFullUrl = oFile.isAbsolute() ? sUrl : (sBaseUrl != null ? sBaseUrl + sUrl : sUrl);
        return this.moHrefs.get(sFullUrl);
    }

    void clearCache() {
        this.mnCurrentCacheSize = 0;
        this.moHrefs.clear();
    }

    int size() {
        return this.moHrefs.size();
    }

    String getBaseUrl() {
        return this.msBaseUrl;
    }

    void setBaseUrl(String sBaseUrl) {
        this.msBaseUrl = ProtocolUtils.normalizeBaseUrl(sBaseUrl);
    }

    String getAlternativeUrl() {
        return this.msAltUrl;
    }

    void setAlternativeUrl(String sAltUrl) {
        this.msAltUrl = ProtocolUtils.normalizeBaseUrl(sAltUrl);
    }

    boolean isTrusted() {
        return this.mbTrusted;
    }

    void isTrusted(boolean bTrusted) {
        this.mbTrusted = bTrusted;
    }

    int getCacheSize() {
        return this.mnCacheSize;
    }

    void setCacheSize(int nCacheSize) {
        this.mnCacheSize = nCacheSize;
    }

    int getCurrentCacheSize() {
        return this.mnCurrentCacheSize;
    }

    /*
     * WARNING - Removed try catching itself - possible behaviour change.
     */
    HrefData getHrefData(String sUrl) {
        HrefData oHrefData;
        block25 : {
            CacheItem oItem = this.get(sUrl);
            assert (oItem != null);
            oHrefData = oItem.moHrefData;
            if (oHrefData == null) {
                int nLastSlash;
                int nSize;
                ByteArrayOutputStream oOutStream;
                StringHolder sRealUrl = new StringHolder();
                InputStream oInStream = null;
                oOutStream = new ByteArrayOutputStream();
                nSize = 0;
                try {
                    oInStream = this.resolveUrl(sUrl, sRealUrl);
                    try {
                        byte[] iBuf = new byte[4096];
                        int nRead = 0;
                        while ((nRead = oInStream.read(iBuf)) > 0) {
                            oOutStream.write(iBuf, 0, nRead);
                            nSize += nRead;
                        }
                    }
                    catch (IOException e) {
                        throw new ExFull(e);
                    }
                }
                finally {
                    try {
                        if (oInStream != null) {
                            oInStream.close();
                        }
                    }
                    catch (IOException ex) {}
                }
                oItem.moHrefData = oHrefData = new HrefData();
                oItem.mnSize = nSize;
                oItem.mbLocked = true;
                this.mnCurrentCacheSize += nSize;
                oItem.mnCacheIndex = ++this.mnCacheIndex;
                AppModel oAppModel = new AppModel(null);
                oAppModel.addFactory(new TemplateModelFactory());
                oAppModel.setHrefHandler(this.moHrefService);
                oAppModel.setIsFragmentDoc(true);
                oItem.moHrefData.setAppModel(oAppModel);
                String sPrevious = this.getImplicitBaseUrl();
                String sBase = sRealUrl.value;
                if (sBase != null && (nLastSlash = sBase.lastIndexOf(47)) > 0) {
                    this.setImplicitBaseUrl(sBase.substring(0, nLastSlash + 1));
                }
                String msPreviousContainerConfigBaseUrl = this.msContainerConfigBaseUrl;
                this.setContainerConfigBaseUrl(null);
                try {
                    XMLStorage oXMLStorage = new XMLStorage();
                    ByteArrayInputStream oMemStream = new ByteArrayInputStream(oOutStream.toByteArray());
                    oOutStream = null;
                    oXMLStorage.loadXDP(oAppModel, oMemStream, (PacketHandler)this, (Object)this, false);
                    oMemStream = null;
                    ArrayList<String> oSearchPath = new ArrayList<String>();
                    if (this.msContainerConfigBaseUrl != null) {
                        oSearchPath.add(this.msContainerConfigBaseUrl);
                    }
                    if (this.msImplicitBaseUrl != null) {
                        oSearchPath.add(this.msImplicitBaseUrl);
                    }
                    if (this.msBaseUrl != null) {
                        oSearchPath.add(this.msBaseUrl);
                    }
                    if (this.msAltUrl != null) {
                        oSearchPath.add(this.msAltUrl);
                    }
                    oAppModel.setFragmentSearchPath(oSearchPath);
                    if (this.mnCurrentCacheSize <= this.mnCacheSize) break block25;
                    CacheItem[] cacheItems = new CacheItem[this.moHrefs.size()];
                    this.moHrefs.values().toArray(cacheItems);
                    Arrays.sort(cacheItems, new Comparator<CacheItem>(){

                        @Override
                        public int compare(CacheItem cacheItem1, CacheItem cacheItem2) {
                            if (cacheItem1.mnCacheIndex < cacheItem2.mnCacheIndex) {
                                return -1;
                            }
                            if (cacheItem1.mnCacheIndex == cacheItem2.mnCacheIndex) {
                                return 0;
                            }
                            return 1;
                        }
                    });
                    for (CacheItem cacheItem : cacheItems) {
                        if (cacheItem.mbLocked || cacheItem.mnCacheIndex == 0) continue;
                        cacheItem.mnCacheIndex = 0;
                        cacheItem.moHrefData = null;
                        this.mnCurrentCacheSize -= cacheItem.mnSize;
                        if (this.mnCurrentCacheSize >= this.mnCacheSize) {
                            continue;
                        }
                        break;
                    }
                }
                finally {
                    oItem.mbLocked = false;
                    this.setImplicitBaseUrl(sPrevious);
                    this.setContainerConfigBaseUrl(msPreviousContainerConfigBaseUrl);
                }
            }
        }
        return oHrefData;
    }

    void setContainerConfigBaseUrl(String sContainerConfigBaseUrl) {
        this.msContainerConfigBaseUrl = ProtocolUtils.normalizeBaseUrl(sContainerConfigBaseUrl);
    }

    private void setImplicitBaseUrl(String sImplicitBaseUrl) {
        this.msImplicitBaseUrl = ProtocolUtils.normalizeBaseUrl(sImplicitBaseUrl);
    }

    private String getImplicitBaseUrl() {
        return this.msImplicitBaseUrl;
    }

    private InputStream resolveUrl(String sURL, StringHolder sRealURL) {
        int nSlash = sURL.indexOf("|");
        if (nSlash > 0) {
            StringBuilder sPathBuf = new StringBuilder(sURL);
            sPathBuf.setCharAt(nSlash, ':');
            sURL = sPathBuf.toString();
        }
        InputStream resolvedStream = null;
        if (!StringUtils.isEmpty(this.msContainerConfigBaseUrl)) {
            resolvedStream = ProtocolUtils.checkUrl(this.msContainerConfigBaseUrl, sURL, this.mbTrusted, sRealURL);
        }
        if (resolvedStream == null && !StringUtils.isEmpty(this.msImplicitBaseUrl)) {
            resolvedStream = ProtocolUtils.checkUrl(this.msImplicitBaseUrl, sURL, this.mbTrusted, sRealURL);
        }
        if (resolvedStream == null && !StringUtils.isEmpty(this.msBaseUrl)) {
            resolvedStream = ProtocolUtils.checkUrl(this.msBaseUrl, sURL, this.mbTrusted, sRealURL);
        }
        if (resolvedStream == null && !StringUtils.isEmpty(this.msAltUrl)) {
            resolvedStream = ProtocolUtils.checkUrl(this.msAltUrl, sURL, this.mbTrusted, sRealURL);
        }
        if (resolvedStream == null) {
            resolvedStream = ProtocolUtils.checkUrl("", sURL, this.mbTrusted, sRealURL);
        }
        if (resolvedStream == null) {
            MsgFormatPos oMsg = new MsgFormatPos(ResId.XFAHrefStoreException);
            oMsg.format(sURL);
            throw new ExFull(oMsg);
        }
        return resolvedStream;
    }

    @Override
    public void filterPackets(Node oPacket, Object data) {
        Node oNode;
        if (!(oPacket instanceof Element)) {
            return;
        }
        String aName = oPacket.getName();
        if (aName == "config") {
            oNode = oPacket;
            if (oNode != null) {
                oNode = oNode.locateChildByName("present", 0);
            }
            if (oNode != null) {
                oNode = oNode.locateChildByName("common", 0);
            }
            if (oNode != null) {
                oNode = oNode.locateChildByName("template", 0);
            }
            if (oNode != null) {
                oNode = oNode.locateChildByName("base", 0);
            }
            if (oNode != null) {
                for (Node oChild = oNode.getFirstXMLChild(); oChild != null; oChild = oChild.getNextXMLSibling()) {
                    if (!(oChild instanceof Chars)) continue;
                    String sTemplateBase = ((Chars)oChild).getData();
                    if (sTemplateBase.length() <= 0) break;
                    assert (data instanceof HrefStore);
                    HrefStore oHrefStore = (HrefStore)data;
                    oHrefStore.setContainerConfigBaseUrl(sTemplateBase);
                    break;
                }
            }
        }
        if (aName != "template" && (oNode = oPacket) != null) {
            oNode.getXFAParent().removeChild(oNode);
        }
    }

    private static final class CacheItem {
        HrefData moHrefData;
        int mnCacheIndex;
        int mnSize;
        boolean mbLocked;

        CacheItem() {
        }
    }

    static final class HrefData {
        private AppModel moAppModel = null;

        HrefData() {
        }

        AppModel getAppModel() {
            return this.moAppModel;
        }

        void setAppModel(AppModel oAppModel) {
            this.moAppModel = oAppModel;
        }
    }

}