/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.jasper.compiler;

import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletContext;

import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
import org.apache.tomcat.Jar;
import org.apache.tomcat.util.descriptor.tld.TaglibXml;
import org.apache.tomcat.util.descriptor.tld.TldParser;
import org.apache.tomcat.util.descriptor.tld.TldResourcePath;
import org.xml.sax.SAXException;

/**
 * This class caches parsed instances of TLD files to remove the need for the
 * same TLD to be parsed for each JSP that references it. It does not protect
 * against multiple threads processing the same, new TLD but it does ensure that
 * each all threads will use the same TLD object after parsing.
 */
public class TldCache {

    public static final String SERVLET_CONTEXT_ATTRIBUTE_NAME =
            TldCache.class.getName();

    private final ServletContext servletContext;
    private final Map<String,TldResourcePath> uriTldResourcePathMap = new HashMap<>();
    private final Map<TldResourcePath,TaglibXmlCacheEntry> tldResourcePathTaglibXmlMap =
            new HashMap<>();
    private final TldParser tldParser;


    public static TldCache getInstance(ServletContext servletContext) {
        if (servletContext == null) {
            throw new IllegalArgumentException(Localizer.getMessage(
                    "org.apache.jasper.compiler.TldCache.servletContextNull"));
        }
        return (TldCache) servletContext.getAttribute(SERVLET_CONTEXT_ATTRIBUTE_NAME);
    }


    public TldCache(ServletContext servletContext,
            Map<String, TldResourcePath> uriTldResourcePathMap,
            Map<TldResourcePath, TaglibXml> tldResourcePathTaglibXmlMap) {
        this.servletContext = servletContext;
        this.uriTldResourcePathMap.putAll(uriTldResourcePathMap);
        for (Entry<TldResourcePath, TaglibXml> entry : tldResourcePathTaglibXmlMap.entrySet()) {
            TldResourcePath tldResourcePath = entry.getKey();
            long lastModified[] = getLastModified(tldResourcePath);
            TaglibXmlCacheEntry cacheEntry = new TaglibXmlCacheEntry(
                    entry.getValue(), lastModified[0], lastModified[1]);
            this.tldResourcePathTaglibXmlMap.put(tldResourcePath, cacheEntry);
        }
        boolean validate = Boolean.parseBoolean(
                servletContext.getInitParameter(Constants.XML_VALIDATION_TLD_INIT_PARAM));
        String blockExternalString = servletContext.getInitParameter(
                Constants.XML_BLOCK_EXTERNAL_INIT_PARAM);
        boolean blockExternal;
        if (blockExternalString == null) {
            blockExternal = true;
        } else {
            blockExternal = Boolean.parseBoolean(blockExternalString);
        }
        tldParser = new TldParser(true, validate, blockExternal);
    }


    public TldResourcePath getTldResourcePath(String uri) {
        return uriTldResourcePathMap.get(uri);
    }


    public TaglibXml getTaglibXml(TldResourcePath tldResourcePath) throws JasperException {
        TaglibXmlCacheEntry cacheEntry = tldResourcePathTaglibXmlMap.get(tldResourcePath);
        if (cacheEntry == null) {
            return null;
        }
        long lastModified[] = getLastModified(tldResourcePath);
        if (lastModified[0] != cacheEntry.getWebAppPathLastModified() ||
                lastModified[1] != cacheEntry.getEntryLastModified()) {
            synchronized (cacheEntry) {
                if (lastModified[0] != cacheEntry.getWebAppPathLastModified() ||
                        lastModified[1] != cacheEntry.getEntryLastModified()) {
                    // Re-parse TLD
                    TaglibXml updatedTaglibXml;
                    try {
                        updatedTaglibXml = tldParser.parse(tldResourcePath);
                    } catch (IOException | SAXException e) {
                        throw new JasperException(e);
                    }
                    cacheEntry.setTaglibXml(updatedTaglibXml);
                    cacheEntry.setWebAppPathLastModified(lastModified[0]);
                    cacheEntry.setEntryLastModified(lastModified[1]);
                }
            }
        }
        return cacheEntry.getTaglibXml();
    }


    private long[] getLastModified(TldResourcePath tldResourcePath) {
        long[] result = new long[2];
        result[0] = -1;
        result[1] = -1;
        try {
            String webappPath = tldResourcePath.getWebappPath();
            if (webappPath != null) {
                // webappPath will be null for JARs containing TLDs that are on
                // the class path but not part of the web application
                URL url = servletContext.getResource(tldResourcePath.getWebappPath());
                URLConnection conn = url.openConnection();
                result[0] = conn.getLastModified();
                if ("file".equals(url.getProtocol())) {
                    // Reading the last modified time opens an input stream so we
                    // need to make sure it is closed again otherwise the TLD file
                    // will be locked until GC runs.
                    conn.getInputStream().close();
                }
            }
            try (Jar jar = tldResourcePath.openJar()) {
                if (jar != null) {
                    result[1] = jar.getLastModified(tldResourcePath.getEntryName());
                }
            }
        } catch (IOException e) {
            // Ignore (shouldn't happen)
        }
        return result;
    }

    private static class TaglibXmlCacheEntry {
        private volatile TaglibXml taglibXml;
        private volatile long webAppPathLastModified;
        private volatile long entryLastModified;

        public TaglibXmlCacheEntry(TaglibXml taglibXml, long webAppPathLastModified,
                long entryLastModified) {
            this.taglibXml = taglibXml;
            this.webAppPathLastModified = webAppPathLastModified;
            this.entryLastModified = entryLastModified;
        }

        public TaglibXml getTaglibXml() {
            return taglibXml;
        }

        public void setTaglibXml(TaglibXml taglibXml) {
            this.taglibXml = taglibXml;
        }

        public long getWebAppPathLastModified() {
            return webAppPathLastModified;
        }

        public void setWebAppPathLastModified(long webAppPathLastModified) {
            this.webAppPathLastModified = webAppPathLastModified;
        }

        public long getEntryLastModified() {
            return entryLastModified;
        }

        public void setEntryLastModified(long entryLastModified) {
            this.entryLastModified = entryLastModified;
        }
    }
}
