/*
 * 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.myfaces.extensions.scripting.loader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.extensions.scripting.loader.support.ClassFileLoader;
import org.apache.myfaces.extensions.scripting.loader.support.ThrowAwayClassLoader;
import org.apache.myfaces.extensions.scripting.loader.support.OverridingClassLoader;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>A class loader implementation that enables you to reload certain classes. It automatically
 * reloads classes if there's a newer version of a .class file available in a specified compilation
 * target path. However, it's also possible to explicitly reload other classes.</p>
 * <p/>
 * <p>This enables you to do both modify and reload various classes that you've used for Spring
 * bean definitions, but it also enables you to reload for example classes depending on those
 * dynamically compiled classes, like factory bean classes. By explicitly reloading a factory
 * bean class the newly loaded factory bean will return updated bean instances as well!</p>
 * <p/>
 * <p>Note that even though this class extends the class URLClassLoader it doesn't use any
 * of its functionalities. This class loader just works similar and provides a similar interface
 * so it's useful to extend the class URLClassLoader as you can treat it like one (especially
 * when it comes to resolving the classpath of a class loader).</p>
 */
public class ReloadingClassLoader extends URLClassLoader {

    /**
     * The system-dependent default name-separator character. Note that it's safe to
     * use this version of the file separator in regex methods, like replaceAll().
     */
    private static String FILE_SEPARATOR = File.separator;

    static {
        if ("\\".equals(FILE_SEPARATOR)) {
            FILE_SEPARATOR = "\\\\";
        }
    }

    /**
     * The logger instance for this class.
     */
    private static final Log logger = LogFactory.getLog(ReloadingClassLoader.class);

    /**
     * A table of class names and the according class loaders. It's basically like
     * a list of classes that this class loader has already loaded. However, the
     * thing is that this class loader isn't actually going to load them as we
     * would loose the possibility to override them then, which is the reason why
     * each class has got its own class loader.
     */
    private Map<String, ThrowAwayClassLoader> classLoaders =
            new HashMap<String, ThrowAwayClassLoader>();

    /**
     * A list of reloading listeners that this class loader notifies once a class
     * has been reloaded. 
     */
    private List<ClassReloadingListener> reloadingListeners = new ArrayList<ClassReloadingListener>();

    /**
     * The target directory for the compiler, i.e. the directory that contains the
     * dynamically compiled .class files.
     */
    private File compilationDirectory;

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

    /**
     * <p>Constructs a new reloading class loader for the specified compilation
     * directory using the default delegation parent class loader. Note that this
     * class loader will only delegate to the parent class loader if there's no
     * dynamically compiled class available.</p>
     *
     * @param compilationDirectory the compilation directory
     */
    public ReloadingClassLoader(File compilationDirectory) {
        super(new URL[0]);
        this.compilationDirectory = compilationDirectory;

        // Register a default logging listener
        registerReloadingListener(new LoggingClassReloadingListener());
    }

    /**
     * <p>Constructs a new reloading class loader for the specified compilation
     * directory using the given delegation parent class loader. Note that this
     * class loader will only delegate to the parent class loader if there's no
     * dynamically compiled class available.</p>
     *
     * @param parentClassLoader    the parent class loader
     * @param compilationDirectory the compilation directory
     */
    public ReloadingClassLoader(ClassLoader parentClassLoader, File compilationDirectory) {
        super(new URL[0], parentClassLoader);
        this.compilationDirectory = compilationDirectory;

        // Register a default logging listener
        registerReloadingListener(new LoggingClassReloadingListener());
    }

    // ------------------------------------------ URLClassLoader methods

    /**
     * <p>Loads the class with the specified binary name. This method searches for classes in the
     * compilation directory that you've specified previously. Note that this class loader recognizes
     * whether the class files have changed, that means, if you recompile and reload a class, you'll
     * get a Class object that represents the recompiled class.</p>
     *
     * @param className the binary name of the class you want to load
     * @param resolve   <tt>true</tt>, if the class is to be resolved
     * @return The resulting <tt>Class</tt> object
     * @throws ClassNotFoundException if the class could not be found
     */
    protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
        // First of all, check if there's a class file available in the compilation target path.
        // It doesn't matter which class we're dealing with at the moment as there's always the
        // possibility that the user is either trying to override a statically compiled class
        // (i.e. a class that has been compiled before deploying the application) or he/she is
        // trying to modify a dynamically compiled class, in which case we should compare
        // timestamps, etc.
        File classFile = resolveClassFile(className);
        if (classFile != null && classFile.exists()) {
            if (classLoaders.containsKey(className)) {
                // Check if the class loader is already outdated, i.e. there is a newer class file available
                // for the class we want to load than the class file we've already loaded. If that's the case
                // we're going to throw away this ClassLoader and create a new one for linkage reasons.
                ThrowAwayClassLoader classLoader = classLoaders.get(className);
                if (classLoader.isOutdated(classFile.lastModified())) {
                    // If the class loader is outdated, create a new one. Otherwise the same class loader
                    // would have to load the same class twice or more often which would cause severe
                    // linkage errors. Actually the JVM wouldn't permit that anyway and throw some
                    // linkage errors / exceptions.
                    reloadClass(className);
                }
            } else {
                if (logger.isTraceEnabled()) {
                    logger.trace("A new dynamic class '"
                            + className + "' has been found by this class loader '" + this + "'.");
                }

                // We haven't loaded this class so far, but there is a .class file available,
                // so we have to reload the given class.
                reloadClass(className);
            }

            ThrowAwayClassLoader classLoader = classLoaders.get(className);
            return classLoader.loadClass(className, resolve);
        } else {
            // Even though there is no class file available, there's still a chance that this
            // class loader has forcefully reloaded a statically compiled class.
            if (classLoaders.containsKey(className)) {
                ThrowAwayClassLoader classLoader = classLoaders.get(className);
                return classLoader.loadClass(className, resolve);
            } else {
                // However, if there's neither a .class file nor a reloadable class loader
                // available, just delegate to the parent class loader.
                return super.loadClass(className, resolve);
            }
        }
    }

    /**
     * <p>Returns the search path of URLs for loading classes, i.e. the
     * given compilation target directory, the directory that contains the
     * dynamically compiled .class files.</p>
     *
     * @return the search path of URLs for loading classes
     */
    public URL[] getURLs() {
        try {
            return new URL[]{ compilationDirectory.toURI().toURL() };
        } catch (IOException ex) {
            logger.error("Couldn't resolve the URL to the compilation directory '" + compilationDirectory + "'.", ex);
            return new URL[0];
        }
    }


    // ------------------------------------------ Public methods

    /**
     * <p>Determines whether the given class has been loaded by a class
     * loader that is already outdated.</p>
     *
     * @param classObj the class you want to check
     * @return <code>true</code, if there is a newer class file available for the given object
     */
    public boolean isOutdated(Class classObj) {
        // Is there even a dynamically compiled class file available for the given class?
        File classFile = resolveClassFile(classObj.getName());
        if (classFile.exists()) {
            // If so, check if we the Class reference has been loaded by a ThrowAwayClassLoader.
            // Otherwise it's definitely outdated and we don't have to compare timestamps.
            if (classObj.getClassLoader() instanceof ThrowAwayClassLoader) {
                // Compare the timestamps in order to determine whether the given Class
                // reference is already outdated.
                ThrowAwayClassLoader classLoader = (ThrowAwayClassLoader) classObj.getClassLoader();
                return classLoader.isOutdated(classFile.lastModified());
            } else {
                return true;
            }
        }

        return false;
    }

    /**
     * <p>Reloads the given class internally explicitly. Note that this class loader usually
     * reloads classes automatically, i.e. this class loader detects if there is a newer
     * version of a class file available in the compilation directory. However, by using
     * this method you tell this class loader to forcefully reload the given class. For
     * example, if you've got a newer version of a dynamically recompiled class and a
     * statically compiled class depending on this one, you can tell this class loader to
     * reload the statically compiled class as well so that it references the correct
     * version of the Class object.</p>
     *
     * @param className the class you want to reload
     */
    public void reloadClass(String className) {
        ThrowAwayClassLoader classLoader;

        File classFile = resolveClassFile(className);
        if (classFile != null && classFile.exists()) {
            classLoader = new ClassFileLoader(className, classFile, this);
        } else {
            classLoader = new OverridingClassLoader(className, this);
        }

        // Replace the class loader in the table and fire the according event.
        ThrowAwayClassLoader oldClassLoader = classLoaders.put(className, classLoader);
        synchronized (reloadingListeners) {
            for (ClassReloadingListener reloadingListener : reloadingListeners) {
                reloadingListener.classReloaded(oldClassLoader, classLoader, className);
            }
        }    
    }

    /**
     * <p>Registers a new reloading listener. Afterwards the given listener
     * will be notified if this class loader reloads or loads a class.</p>
     *
     * @param reloadingListener the reloading listener you want to register
     */
    public void registerReloadingListener(ClassReloadingListener reloadingListener) {
        synchronized (reloadingListeners) {
            if (reloadingListener != null) {
                reloadingListeners.add(reloadingListener);
            }
        }
    }

    /**
     * <p>Returns a copy of the current reloading class loader with the only difference
     * being the parent class loader to use. Use this method if you just want to replace
     * the parent class loader (obviously you can't do that after a ClassLoader has been
     * created, hence a copy is created).</p>
     *
     * @param parentClassLoader the parent ClassLoader to use
     * @return a copy of the current reloading class loader
     */
    @SuppressWarnings("unused")
    public ReloadingClassLoader cloneWithParentClassLoader(ClassLoader parentClassLoader) {
        ReloadingClassLoader classLoader =
                new ReloadingClassLoader(parentClassLoader, compilationDirectory);

        // Note that we don't have to create "deep copies" as the class loaders in the map
        // are immutable anyway (they are only supposed to load a single class) and additionally
        // this map doesn't contain classes that have been loaded using the current parent
        // class loader!
        classLoader.classLoaders = new HashMap<String, ThrowAwayClassLoader>(classLoaders);
        classLoader.reloadingListeners = new ArrayList<ClassReloadingListener>(reloadingListeners);

        return classLoader;
    }

    // ------------------------------------------ Utility methods

    /**
     * <p>Resolves and returns a File handle that represents the class file of
     * the given class on the file system. However, note that this method only
     * returns <code>null</code> if an error occured while resolving the class
     * file. A non-null valuee doesn't necessarily mean that the class file
     * actually exists. In oder to check the existence call the according
     * method on the returned object.</p>
     *
     * @param className the name of the class that you want to resolve
     * @return a File handle that represents the class file of the given class
     *         on the file system
     * @see java.io.File#exists()
     */
    protected File resolveClassFile(String className) {
        // This method just has to look in the specified compilation directory. The
        // relative class file path can be computed from the class name.
        return new File(compilationDirectory,
                className.replaceAll("\\.", FILE_SEPARATOR).concat(".class"));
    }

    // ------------------------------------------ Private classes

    private static class LoggingClassReloadingListener implements ClassReloadingListener {

        public void classReloaded(ThrowAwayClassLoader oldClassLoader, ThrowAwayClassLoader newClassLoader, String className) {
            if (logger.isInfoEnabled()) {
                if (oldClassLoader != null) {
                    logger.info("Replaced the class loader '" + oldClassLoader + "' with the class loader '"
                            + newClassLoader + "' as this class loader is supposed to reload the class '" + className + "'.");
                } else {
                    logger.info("Installed a new class loader '" + newClassLoader + "' for the class '"
                            + className + "' as this class loader is supposed to reload it.");
                }
            }
        }
    }

}
