/**
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 2010 Bull S.A.S.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.web.tomcat7.loader;

import java.io.InputStream;
import java.net.URL;

import org.apache.catalina.loader.WebappClassLoader;

/**
 * This {@code WebappClassLoader} disable the system ClassLoader direct access
 * from web applications. It make them fit better in the "standard" module classloader
 * chain: a module with just 1 parent.
 *
 * The system ClassLoader will still be accessed, but not in the first
 * place: so that OSGi provided JAX-WS API have a chance to make it before
 * the system ones AND applications relying on resources available from
 * system loader will continue to find their resources.
 */
public class NoSystemAccessWebappClassLoader extends WebappClassLoader {

    /**
     * The unique instance of disabled ClassLoader.
     */
    private static final ClassLoader DISABLED_LOADER = new DisabledClassLoader();

    /**
     * Construct a new ClassLoader with no defined repositories and no
     * parent ClassLoader.
     */
    public NoSystemAccessWebappClassLoader(ClassLoader parent) {
        super(parent);
        // Overwrite the system ClassLoader in use.
        system = DISABLED_LOADER;

        // avoid bug JONAS-245 by making Tomcat not destroy the root logger
        setClearReferencesLogFactoryRelease(false);
    }

    /**
     * This disabled loader returns null on all methods used from
     * the tomcat WebappClassLoader (getResourceAsStream() use getResource()
     * under the hood, so no need to override it).
     */
    private static class DisabledClassLoader extends ClassLoader {
        /**
         * Loads the class with the specified <a href="#name">binary name</a>.
         * This method searches for classes in the same manner as the {@link
         * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
         * machine to resolve class references.  Invoking this method is equivalent
         * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
         * false)</tt>}.  </p>
         *
         * @param name The <a href="#name">binary name</a> of the class
         * @return The resulting <tt>Class</tt> object
         * @throws ClassNotFoundException If the class was not found
         */
        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            return null;
        }

        /**
         * Finds the resource with the given name.  A resource is some data
         * (images, audio, text, etc) that can be accessed by class code in a way
         * that is independent of the location of the code.
         * <p/>
         * <p> The name of a resource is a '<tt>/</tt>'-separated path name that
         * identifies the resource.
         * <p/>
         * <p> This method will first search the parent class loader for the
         * resource; if the parent is <tt>null</tt> the path of the class loader
         * built-in to the virtual machine is searched.  That failing, this method
         * will invoke {@link #findResource(String)} to find the resource.  </p>
         *
         * @param name The resource name
         * @return A <tt>URL</tt> object for reading the resource, or
         *         <tt>null</tt> if the resource could not be found or the invoker
         *         doesn't have adequate  privileges to get the resource.
         * @since 1.1
         */
        @Override
        public URL getResource(String name) {
            return null;
        }
    }

}
