/*
 * 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;

import java.io.File;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;

import jakarta.servlet.ServletConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.jsp.tagext.TagLibraryInfo;

import org.apache.jasper.compiler.JspConfig;
import org.apache.jasper.compiler.Localizer;
import org.apache.jasper.compiler.TagPluginManager;
import org.apache.jasper.compiler.TldCache;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;

/**
 * A class to hold all init parameters specific to the JSP engine.
 */
public final class EmbeddedServletOptions implements Options {

    // Logger
    private final Log log = LogFactory.getLog(EmbeddedServletOptions.class); // must not be static

    private final Properties settings = new Properties();

    /**
     * Is Jasper being used in development mode?
     */
    private boolean development = true;

    /**
     * Should Ant fork its java compiles of JSP pages.
     */
    public boolean fork = true;

    /**
     * Do you want to keep the generated Java files around?
     */
    private boolean keepGenerated = true;

    /**
     * How should template text that consists entirely of whitespace be handled?
     */
    private TrimSpacesOption trimSpaces = TrimSpacesOption.FALSE;

    /**
     * Determines whether tag handler pooling is enabled.
     */
    private boolean isPoolingEnabled = true;

    /**
     * Do you want support for "mapped" files? This will generate servlet that has a print statement per line of the JSP
     * file. This seems like a really nice feature to have for debugging.
     */
    private boolean mappedFile = true;

    /**
     * Do we want to include debugging information in the class file?
     */
    private boolean classDebugInfo = true;

    /**
     * Background compile thread check interval in seconds.
     */
    private int checkInterval = 0;

    /**
     * Is the generation of SMAP info for JSR45 debugging suppressed?
     */
    private boolean isSmapSuppressed = false;

    /**
     * Should SMAP info for JSR45 debugging be dumped to a file?
     */
    private boolean isSmapDumped = false;

    /**
     * Are Text strings to be generated as char arrays?
     */
    private boolean genStringAsCharArray = false;

    private boolean errorOnUseBeanInvalidClassAttribute = true;

    /**
     * I want to see my generated servlets. Which directory are they in?
     */
    private final File scratchDir;

    /**
     * What classpath should I use while compiling generated servlets?
     */
    private String classpath = null;

    /**
     * Compiler to use.
     */
    private String compiler = null;

    /**
     * Compiler target VM.
     */
    private String compilerTargetVM = "21";

    /**
     * The compiler source VM.
     */
    private String compilerSourceVM = "21";

    /**
     * The compiler class name.
     */
    private String compilerClassName = null;

    /**
     * Cache for the TLD URIs, resource paths and parsed files.
     */
    private TldCache tldCache = null;

    /**
     * Jsp config information
     */
    private JspConfig jspConfig = null;

    /**
     * TagPluginManager
     */
    private TagPluginManager tagPluginManager = null;

    /**
     * Java platform encoding to generate the JSP page servlet.
     */
    private String javaEncoding = "UTF-8";

    /**
     * Modification test interval.
     */
    private int modificationTestInterval = 4;

    /**
     * Is re-compilation attempted immediately after a failure?
     */
    private boolean recompileOnFail = false;

    /**
     * Is generation of X-Powered-By response header enabled/disabled?
     */
    private boolean xpoweredBy;

    /**
     * Should we include a source fragment in exception messages, which could be displayed to the developer ?
     */
    private boolean displaySourceFragment = true;


    /**
     * The maximum number of loaded jsps per web-application. If there are more jsps loaded, they will be unloaded.
     */
    private int maxLoadedJsps = -1;

    /**
     * The idle time in seconds after which a JSP is unloaded. If unset or less or equal than 0, no jsps are unloaded.
     */
    private int jspIdleTimeout = -1;

    /**
     * Should JSP.1.6 be applied strictly to attributes defined using scriptlet expressions?
     */
    private boolean strictQuoteEscaping = true;

    /**
     * When EL is used in JSP attribute values, should the rules for quoting of attributes described in JSP.1.6 be
     * applied to the expression?
     */
    private boolean quoteAttributeEL = true;

    private String variableForExpressionFactory = "_el_expressionfactory";

    private String variableForInstanceManager = "_jsp_instancemanager";

    private boolean poolTagsWithExtends = false;

    private boolean strictGetProperty = true;

    private boolean strictWhitespace = true;

    private String jspServletBase = "org.apache.jasper.runtime.HttpJspBase";

    private String serviceMethodName = "_jspService";

    private String servletClasspathAttribute = "org.apache.catalina.jsp_classpath";

    private String jspPrecompilationQueryParameter = "jsp_precompile";

    private String generatedJspPackageName = "org.apache.jsp";

    private String generatedTagFilePackageName = "org.apache.jsp.tag";

    private String tempVariableNamePrefix = "_jspx_temp";

    private boolean useInstanceManagerForTags = false;

    private String useNonstandardTagOptimizations;

    public String getProperty(String name) {
        return settings.getProperty(name);
    }

    public void setProperty(String name, String value) {
        if (name != null && value != null) {
            settings.setProperty(name, value);
        }
    }

    public void setQuoteAttributeEL(boolean b) {
        this.quoteAttributeEL = b;
    }

    @Override
    public boolean getQuoteAttributeEL() {
        return quoteAttributeEL;
    }

    @Override
    public boolean getKeepGenerated() {
        return keepGenerated;
    }

    @Override
    public TrimSpacesOption getTrimSpaces() {
        return trimSpaces;
    }

    @Override
    public boolean isPoolingEnabled() {
        return isPoolingEnabled;
    }

    @Override
    public boolean getMappedFile() {
        return mappedFile;
    }

    @Override
    public boolean getClassDebugInfo() {
        return classDebugInfo;
    }

    @Override
    public int getCheckInterval() {
        return checkInterval;
    }

    @Override
    public int getModificationTestInterval() {
        return modificationTestInterval;
    }

    @Override
    public boolean getRecompileOnFail() {
        return recompileOnFail;
    }

    @Override
    public boolean getDevelopment() {
        return development;
    }

    @Override
    public boolean isSmapSuppressed() {
        return isSmapSuppressed;
    }

    @Override
    public boolean isSmapDumped() {
        return isSmapDumped;
    }

    @Override
    public boolean genStringAsCharArray() {
        return this.genStringAsCharArray;
    }

    @Override
    public File getScratchDir() {
        return scratchDir;
    }

    @Override
    public String getClassPath() {
        return classpath;
    }

    @Override
    public boolean isXpoweredBy() {
        return xpoweredBy;
    }

    @Override
    public String getCompiler() {
        return compiler;
    }

    @Override
    public String getCompilerTargetVM() {
        return compilerTargetVM;
    }

    @Override
    public String getCompilerSourceVM() {
        return compilerSourceVM;
    }

    @Override
    public String getCompilerClassName() {
        return compilerClassName;
    }

    @Override
    public boolean getErrorOnUseBeanInvalidClassAttribute() {
        return errorOnUseBeanInvalidClassAttribute;
    }

    public void setErrorOnUseBeanInvalidClassAttribute(boolean b) {
        errorOnUseBeanInvalidClassAttribute = b;
    }

    @Override
    public TldCache getTldCache() {
        return tldCache;
    }

    public void setTldCache(TldCache tldCache) {
        this.tldCache = tldCache;
    }

    @Override
    public String getJavaEncoding() {
        return javaEncoding;
    }

    @Override
    public boolean getFork() {
        return fork;
    }

    @Override
    public JspConfig getJspConfig() {
        return jspConfig;
    }

    @Override
    public TagPluginManager getTagPluginManager() {
        return tagPluginManager;
    }

    @Override
    public boolean isCaching() {
        return false;
    }

    @Override
    public Map<String,TagLibraryInfo> getCache() {
        return null;
    }

    @Override
    public boolean getDisplaySourceFragment() {
        return displaySourceFragment;
    }

    @Override
    public int getMaxLoadedJsps() {
        return maxLoadedJsps;
    }

    @Override
    public int getJspIdleTimeout() {
        return jspIdleTimeout;
    }

    @Override
    public boolean getStrictQuoteEscaping() {
        return strictQuoteEscaping;
    }

    @Override
    public String getVariableForExpressionFactory() {
        return variableForExpressionFactory;
    }

    @Override
    public String getVariableForInstanceManager() {
        return variableForInstanceManager;
    }

    @Override
    public boolean getPoolTagsWithExtends() {
        return poolTagsWithExtends;
    }

    @Override
    public boolean getStrictGetProperty() {
        return strictGetProperty;
    }

    @Override
    public boolean getStrictWhitespace() {
        return strictWhitespace;
    }

    @Override
    public String getJspServletBase() {
        return jspServletBase;
    }

    @Override
    public String getServiceMethodName() {
        return serviceMethodName;
    }

    @Override
    public String getServletClasspathAttribute() {
        return servletClasspathAttribute;
    }

    @Override
    public String getJspPrecompilationQueryParameter() {
        return jspPrecompilationQueryParameter;
    }

    @Override
    public String getGeneratedJspPackageName() {
        return generatedJspPackageName;
    }

    @Override
    public String getGeneratedTagFilePackageName() {
        return generatedTagFilePackageName;
    }

    @Override
    public String getTempVariableNamePrefix() {
        return tempVariableNamePrefix;
    }

    @Override
    public boolean getUseInstanceManagerForTags() {
        return useInstanceManagerForTags;
    }

    @Override
    public String getUseNonstandardTagOptimizations() {
        return useNonstandardTagOptimizations;
    }

    /**
     * Create an EmbeddedServletOptions object using data available from ServletConfig and ServletContext.
     *
     * @param config  The Servlet config
     * @param context The Servlet context
     */
    public EmbeddedServletOptions(ServletConfig config, ServletContext context) {

        Enumeration<String> enumeration = config.getInitParameterNames();
        while (enumeration.hasMoreElements()) {
            String k = enumeration.nextElement();
            String v = config.getInitParameter(k);
            setProperty(k, v);
        }

        String keepgen = config.getInitParameter("keepgenerated");
        if (keepgen != null) {
            if (keepgen.equalsIgnoreCase("true")) {
                this.keepGenerated = true;
            } else if (keepgen.equalsIgnoreCase("false")) {
                this.keepGenerated = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.keepgen"));
                }
            }
        }


        String trimsp = config.getInitParameter("trimSpaces");
        if (trimsp != null) {
            try {
                trimSpaces = TrimSpacesOption.valueOf(trimsp.toUpperCase(Locale.ENGLISH));
            } catch (IllegalArgumentException iae) {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.trimspaces"), iae);
                }
            }
        }

        this.isPoolingEnabled = true;
        String poolingEnabledParam = config.getInitParameter("enablePooling");
        if (poolingEnabledParam != null && !poolingEnabledParam.equalsIgnoreCase("true")) {
            if (poolingEnabledParam.equalsIgnoreCase("false")) {
                this.isPoolingEnabled = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.enablePooling"));
                }
            }
        }

        String mapFile = config.getInitParameter("mappedfile");
        if (mapFile != null) {
            if (mapFile.equalsIgnoreCase("true")) {
                this.mappedFile = true;
            } else if (mapFile.equalsIgnoreCase("false")) {
                this.mappedFile = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.mappedFile"));
                }
            }
        }

        String debugInfo = config.getInitParameter("classdebuginfo");
        if (debugInfo != null) {
            if (debugInfo.equalsIgnoreCase("true")) {
                this.classDebugInfo = true;
            } else if (debugInfo.equalsIgnoreCase("false")) {
                this.classDebugInfo = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.classDebugInfo"));
                }
            }
        }

        String checkInterval = config.getInitParameter("checkInterval");
        if (checkInterval != null) {
            try {
                this.checkInterval = Integer.parseInt(checkInterval);
            } catch (NumberFormatException ex) {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.checkInterval"));
                }
            }
        }

        String modificationTestInterval = config.getInitParameter("modificationTestInterval");
        if (modificationTestInterval != null) {
            try {
                this.modificationTestInterval = Integer.parseInt(modificationTestInterval);
            } catch (NumberFormatException ex) {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.modificationTestInterval"));
                }
            }
        }

        String recompileOnFail = config.getInitParameter("recompileOnFail");
        if (recompileOnFail != null) {
            if (recompileOnFail.equalsIgnoreCase("true")) {
                this.recompileOnFail = true;
            } else if (recompileOnFail.equalsIgnoreCase("false")) {
                this.recompileOnFail = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.recompileOnFail"));
                }
            }
        }
        String development = config.getInitParameter("development");
        if (development != null) {
            if (development.equalsIgnoreCase("true")) {
                this.development = true;
            } else if (development.equalsIgnoreCase("false")) {
                this.development = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.development"));
                }
            }
        }

        String suppressSmap = config.getInitParameter("suppressSmap");
        if (suppressSmap != null) {
            if (suppressSmap.equalsIgnoreCase("true")) {
                isSmapSuppressed = true;
            } else if (suppressSmap.equalsIgnoreCase("false")) {
                isSmapSuppressed = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.suppressSmap"));
                }
            }
        }

        String dumpSmap = config.getInitParameter("dumpSmap");
        if (dumpSmap != null) {
            if (dumpSmap.equalsIgnoreCase("true")) {
                isSmapDumped = true;
            } else if (dumpSmap.equalsIgnoreCase("false")) {
                isSmapDumped = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.dumpSmap"));
                }
            }
        }

        String genCharArray = config.getInitParameter("genStringAsCharArray");
        if (genCharArray != null) {
            if (genCharArray.equalsIgnoreCase("true")) {
                genStringAsCharArray = true;
            } else if (genCharArray.equalsIgnoreCase("false")) {
                genStringAsCharArray = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.genchararray"));
                }
            }
        }

        String errBeanClass = config.getInitParameter("errorOnUseBeanInvalidClassAttribute");
        if (errBeanClass != null) {
            if (errBeanClass.equalsIgnoreCase("true")) {
                errorOnUseBeanInvalidClassAttribute = true;
            } else if (errBeanClass.equalsIgnoreCase("false")) {
                errorOnUseBeanInvalidClassAttribute = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.errBean"));
                }
            }
        }

        String classpath = config.getInitParameter("classpath");
        if (classpath != null) {
            this.classpath = classpath;
        }

        String useNonstandardTagOptimizations = config.getInitParameter("useNonstandardTagOptimizations");
        if (useNonstandardTagOptimizations != null) {
            this.useNonstandardTagOptimizations = useNonstandardTagOptimizations;
        }

        /*
         * scratchdir
         */
        String dir = config.getInitParameter("scratchdir");
        if (dir != null) {
            scratchDir = new File(dir);
        } else {
            scratchDir = (File) context.getAttribute(ServletContext.TEMPDIR);
        }
        if (scratchDir == null) {
            log.fatal(Localizer.getMessage("jsp.error.no.scratch.dir"));
            return;
        }

        if (!(scratchDir.exists() && scratchDir.canRead() && scratchDir.canWrite() && scratchDir.isDirectory())) {
            log.fatal(Localizer.getMessage("jsp.error.bad.scratch.dir", scratchDir.getAbsolutePath()));
        }

        this.compiler = config.getInitParameter("compiler");

        String compilerTargetVM = config.getInitParameter("compilerTargetVM");
        if (compilerTargetVM != null) {
            this.compilerTargetVM = compilerTargetVM;
        }

        String compilerSourceVM = config.getInitParameter("compilerSourceVM");
        if (compilerSourceVM != null) {
            this.compilerSourceVM = compilerSourceVM;
        }

        String javaEncoding = config.getInitParameter("javaEncoding");
        if (javaEncoding != null) {
            this.javaEncoding = javaEncoding;
        }

        String compilerClassName = config.getInitParameter("compilerClassName");
        if (compilerClassName != null) {
            this.compilerClassName = compilerClassName;
        }

        String fork = config.getInitParameter("fork");
        if (fork != null) {
            if (fork.equalsIgnoreCase("true")) {
                this.fork = true;
            } else if (fork.equalsIgnoreCase("false")) {
                this.fork = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.fork"));
                }
            }
        }

        String xpoweredBy = config.getInitParameter("xpoweredBy");
        if (xpoweredBy != null) {
            if (xpoweredBy.equalsIgnoreCase("true")) {
                this.xpoweredBy = true;
            } else if (xpoweredBy.equalsIgnoreCase("false")) {
                this.xpoweredBy = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.xpoweredBy"));
                }
            }
        }

        String displaySourceFragment = config.getInitParameter("displaySourceFragment");
        if (displaySourceFragment != null) {
            if (displaySourceFragment.equalsIgnoreCase("true")) {
                this.displaySourceFragment = true;
            } else if (displaySourceFragment.equalsIgnoreCase("false")) {
                this.displaySourceFragment = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.displaySourceFragment"));
                }
            }
        }

        String maxLoadedJsps = config.getInitParameter("maxLoadedJsps");
        if (maxLoadedJsps != null) {
            try {
                this.maxLoadedJsps = Integer.parseInt(maxLoadedJsps);
            } catch (NumberFormatException ex) {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.maxLoadedJsps", "" + this.maxLoadedJsps));
                }
            }
        }

        String jspIdleTimeout = config.getInitParameter("jspIdleTimeout");
        if (jspIdleTimeout != null) {
            try {
                this.jspIdleTimeout = Integer.parseInt(jspIdleTimeout);
            } catch (NumberFormatException ex) {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.jspIdleTimeout", "" + this.jspIdleTimeout));
                }
            }
        }

        String strictQuoteEscaping = config.getInitParameter("strictQuoteEscaping");
        if (strictQuoteEscaping != null) {
            if (strictQuoteEscaping.equalsIgnoreCase("true")) {
                this.strictQuoteEscaping = true;
            } else if (strictQuoteEscaping.equalsIgnoreCase("false")) {
                this.strictQuoteEscaping = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.strictQuoteEscaping"));
                }
            }
        }

        String quoteAttributeEL = config.getInitParameter("quoteAttributeEL");
        if (quoteAttributeEL != null) {
            if (quoteAttributeEL.equalsIgnoreCase("true")) {
                this.quoteAttributeEL = true;
            } else if (quoteAttributeEL.equalsIgnoreCase("false")) {
                this.quoteAttributeEL = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.quoteAttributeEL"));
                }
            }
        }

        String variableForExpressionFactory = config.getInitParameter("variableForExpressionFactory");
        if (variableForExpressionFactory != null) {
            this.variableForExpressionFactory = variableForExpressionFactory;
        }

        String variableForInstanceManager = config.getInitParameter("variableForInstanceManager");
        if (variableForInstanceManager != null) {
            this.variableForInstanceManager = variableForInstanceManager;
        }

        String poolTagsWithExtends = config.getInitParameter("poolTagsWithExtends");
        if (poolTagsWithExtends != null) {
            if (poolTagsWithExtends.equalsIgnoreCase("true")) {
                this.poolTagsWithExtends = true;
            } else if (poolTagsWithExtends.equalsIgnoreCase("false")) {
                this.poolTagsWithExtends = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.poolTagsWithExtends"));
                }
            }
        }

        String strictGetProperty = config.getInitParameter("strictGetProperty");
        if (strictGetProperty != null) {
            if (strictGetProperty.equalsIgnoreCase("true")) {
                this.strictGetProperty = true;
            } else if (strictGetProperty.equalsIgnoreCase("false")) {
                this.strictGetProperty = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.strictGetProperty"));
                }
            }
        }

        String strictWhitespace = config.getInitParameter("strictWhitespace");
        if (strictWhitespace != null) {
            if (strictWhitespace.equalsIgnoreCase("true")) {
                this.strictWhitespace = true;
            } else if (strictWhitespace.equalsIgnoreCase("false")) {
                this.strictWhitespace = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.strictWhitespace"));
                }
            }
        }

        String jspServletBase = config.getInitParameter("jspServletBase");
        if (jspServletBase != null) {
            this.jspServletBase = jspServletBase;
        }

        String serviceMethodName = config.getInitParameter("serviceMethodName");
        if (serviceMethodName != null) {
            this.serviceMethodName = serviceMethodName;
        }

        String servletClasspathAttribute = config.getInitParameter("servletClasspathAttribute");
        if (servletClasspathAttribute != null) {
            this.servletClasspathAttribute = servletClasspathAttribute;
        }

        String jspPrecompilationQueryParameter = config.getInitParameter("jspPrecompilationQueryParameter");
        if (jspPrecompilationQueryParameter != null) {
            this.jspPrecompilationQueryParameter = jspPrecompilationQueryParameter;
        }

        String generatedJspPackageName = config.getInitParameter("generatedJspPackageName");
        if (generatedJspPackageName != null) {
            this.generatedJspPackageName = generatedJspPackageName;
        }

        String generatedTagFilePackageName = config.getInitParameter("generatedTagFilePackageName");
        if (generatedTagFilePackageName != null) {
            this.generatedTagFilePackageName = generatedTagFilePackageName;
        }

        String tempVariableNamePrefix = config.getInitParameter("tempVariableNamePrefix");
        if (tempVariableNamePrefix != null) {
            this.tempVariableNamePrefix = tempVariableNamePrefix;
        }

        String useInstanceManagerForTags = config.getInitParameter("useInstanceManagerForTags");
        if (useInstanceManagerForTags != null) {
            if (useInstanceManagerForTags.equalsIgnoreCase("true")) {
                this.useInstanceManagerForTags = true;
            } else if (useInstanceManagerForTags.equalsIgnoreCase("false")) {
                this.useInstanceManagerForTags = false;
            } else {
                if (log.isWarnEnabled()) {
                    log.warn(Localizer.getMessage("jsp.warning.useInstanceManagerForTags"));
                }
            }
        }

        // Set up the global Tag Libraries location cache for this
        // web-application.
        tldCache = TldCache.getInstance(context);

        // Set up the jsp config info for this web app.
        jspConfig = new JspConfig(context);

        // Create a Tag plugin instance
        tagPluginManager = new TagPluginManager(context);
    }

}

