/*
 * Copyright (c) 1997-2018 Oracle and/or its affiliates. All rights reserved.
 * Copyright 2004 The Apache Software Foundation
 *
 * Licensed 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.catalina.core;


import org.apache.catalina.ContainerEvent;
import org.apache.catalina.LogFacade;
import org.apache.catalina.deploy.FilterDef;
import org.apache.catalina.security.SecurityUtil;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.ResourceBundle;



/**
 * Implementation of a <code>jakarta.servlet.FilterConfig</code> useful in
 * managing the filter instances instantiated when a web application
 * is first started.
 *
 * @author Craig R. McClanahan
 * @version $Revision: 1.6 $ $Date: 2007/03/22 18:04:04 $
 */

final class ApplicationFilterConfig implements FilterConfig, Serializable {

    private static final Logger log = LogFacade.getLogger();
    private static final ResourceBundle rb = log.getResourceBundle();

    // ----------------------------------------------------------- Constructors


    /**
     * Construct a new ApplicationFilterConfig for the specified filter
     * definition.
     *
     * @param context The context with which we are associated
     * @param filterDef Filter definition for which a FilterConfig is to be
     *  constructed
     *
     * @exception ClassCastException if the specified class does not implement
     *  the <code>jakarta.servlet.Filter</code> interface
     * @exception ClassNotFoundException if the filter class cannot be found
     * @exception IllegalAccessException if the filter class cannot be
     *  publicly instantiated
     * @exception InstantiationException if an exception occurs while
     *  instantiating the filter object
     * @exception ServletException if thrown by the filter's init() method
     */
    public ApplicationFilterConfig(StandardContext context,
                                   FilterDef filterDef)
        throws ClassCastException, ClassNotFoundException,
               IllegalAccessException, InstantiationException,
               ServletException {
        super();
        this.context = context;
        setFilterDef(filterDef);
        // init the filter
        try {
            getFilter();
        } catch(InstantiationException iex) {
            throw iex;
        } catch(Exception ex) {
            InstantiationException iex = new InstantiationException();
            iex.initCause(ex);
            throw iex;
        }
    }


    // ----------------------------------------------------- Instance Variables


    /**
     * The Context with which we are associated.
     */
    private transient StandardContext context = null;


    /**
     * The application Filter we are configured for.
     */
    private transient Filter filter = null;


    /**
     * The <code>FilterDef</code> that defines our associated Filter.
     */
    private FilterDef filterDef = null;


    /**
     * Does the filter instance need to be initialized?
     */
    private boolean needInitialize = true;


    // --------------------------------------------------- FilterConfig Methods


    /**
     * Return the name of the filter we are configuring.
     */
    public String getFilterName() {
        return (filterDef.getFilterName());
    }


    /**
     * Checks if this filter has been annotated or flagged in the deployment
     * descriptor as being able to support asynchronous operations.
     *
     * @return true if this filter supports async operations, and false
     * otherwise
     */
    public boolean isAsyncSupported() {
        return filterDef.isAsyncSupported();
    }


    /**
     * Return a <code>String</code> containing the value of the named
     * initialization parameter, or <code>null</code> if the parameter
     * does not exist.
     *
     * @param name Name of the requested initialization parameter
     */
    public String getInitParameter(String name) {
        return filterDef.getInitParameter(name);
    }


    /**
     * Return an <code>Enumeration</code> of the names of the initialization
     * parameters for this Filter.
     */
    public Enumeration<String> getInitParameterNames() {
        return filterDef.getInitParameterNames();
    }


    /**
     * Return the ServletContext of our associated web application.
     */
    public ServletContext getServletContext() {
        return (this.context.getServletContext());
    }


    /**
     * Return a String representation of this object.
     */
    public String toString() {
        StringBuilder sb = new StringBuilder("ApplicationFilterConfig[");
        sb.append("name=");
        sb.append(filterDef.getFilterName());
        sb.append(", filterClass=");
        sb.append(filterDef.getFilterClassName());
        sb.append("]");
        return (sb.toString());
    }


    // -------------------------------------------------------- Package Methods


    /**
     * Return the application Filter we are configured for.
     */
    synchronized Filter getFilter() throws Exception {

        // Return the existing filter instance, if any
        if (filter != null && !needInitialize) {
            return filter;
        }

        if (filter == null) {
            Class<? extends Filter> clazz = filterDef.getFilterClass();
            if (clazz == null) {
                // Identify the class loader we will be using
                ClassLoader classLoader = null;
                String filterClassName = filterDef.getFilterClassName();
                if (filterClassName.startsWith("org.apache.catalina.")) {
                    classLoader = this.getClass().getClassLoader();
                } else {
                    classLoader = context.getLoader().getClassLoader();
                }

                // Instantiate a new instance of this filter and return it
                clazz = loadFilterClass(classLoader, filterClassName);
            }

            this.filter = context.createFilterInstance(clazz);
        }

        // START PWC 1.2
        if (context != null) {
            context.fireContainerEvent(
                ContainerEvent.BEFORE_FILTER_INITIALIZED,
                filter);
        }
        // END PWC 1.2

        filter.init(this);
        needInitialize = false;

        // START PWC 1.2
        if (context != null) {
            context.fireContainerEvent(ContainerEvent.AFTER_FILTER_INITIALIZED,
                                       filter);
        }
        // END PWC 1.2

        return (this.filter);
    }

    @SuppressWarnings("unchecked")
    private Class<? extends Filter> loadFilterClass(ClassLoader classLoader,
            String filterClassName) throws ClassNotFoundException {
        return (Class<? extends Filter>)classLoader.loadClass(filterClassName);
    }


    /**
     * Return the filter definition we are configured for.
     */
    FilterDef getFilterDef() {
        return (this.filterDef);
    }


    /**
     * Release the Filter instance associated with this FilterConfig,
     * if there is one.
     */
    void release() {

        if (this.filter != null){

            if (context != null) {
                context.fireContainerEvent(
                    ContainerEvent.BEFORE_FILTER_DESTROYED,
                    filter);
            }

            // START SJS WS 7.0 6236329
            //if( System.getSecurityManager() != null) {
            if ( SecurityUtil.executeUnderSubjectDoAs() ){
            // END OF SJS WS 7.0 6236329
                try{
                    SecurityUtil.doAsPrivilege("destroy",
                                               filter);
                    SecurityUtil.remove(filter);
                } catch(java.lang.Exception ex){
                    String msg = rb.getString(LogFacade.DO_AS_PRIVILEGE);
                    log.log(Level.SEVERE, msg, ex);
                }
            } else {
                filter.destroy();
            }

            if (context != null) {
                context.fireContainerEvent(
                    ContainerEvent.AFTER_FILTER_DESTROYED,
                    filter);
                // See GlassFish IT 7071
                context = null;
            }

        }

        this.filter = null;
        needInitialize = true;
     }


    /**
     * Set the filter definition we are configured for.  This has the side
     * effect of instantiating an instance of the corresponding filter class.
     *
     * @param filterDef The new filter definition
     *
     * @exception ClassCastException if the specified class does not implement
     *  the <code>jakarta.servlet.Filter</code> interface
     * @exception ClassNotFoundException if the filter class cannot be found
     * @exception IllegalAccessException if the filter class cannot be
     *  publicly instantiated
     * @exception InstantiationException if an exception occurs while
     *  instantiating the filter object
     * @exception ServletException if thrown by the filter's init() method
     */
    void setFilterDef(FilterDef filterDef)
        throws ClassCastException, ClassNotFoundException,
               IllegalAccessException, InstantiationException,
               ServletException {

        this.filterDef = filterDef;
        if (filterDef == null) {

            // Release any previously allocated filter instance
            if (this.filter != null){
                // START SJS WS 7.0 6236329
                //if( System.getSecurityManager() != null) {
                if ( SecurityUtil.executeUnderSubjectDoAs() ){
                // END OF SJS WS 7.0 6236329
                    try{
                        SecurityUtil.doAsPrivilege("destroy",
                                                   filter);
                        SecurityUtil.remove(filter);
                    } catch(java.lang.Exception ex){
                        String msg = rb.getString(LogFacade.DO_AS_PRIVILEGE);
                        log.log(Level.SEVERE, msg, ex);
                    }
                } else {
                    filter.destroy();
                }
            }
            this.filter = null;

        } else {
            filter = filterDef.getFilter();
        }
    }

}
