/*
 * 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
     */
    public ReloadingClassLoader cloneWithParentClassLoader(ClassLoader parentClassLoader) {
        ReloadingClassLoader classLoader =
                cloneClassLoader(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>Creates and returns new instance of a reloading class loader which is basically a clone of this one.</p>
     *
     */
    protected ReloadingClassLoader cloneClassLoader(ClassLoader parentClassLoader, File compilationDirectory) {
        return new ReloadingClassLoader(parentClassLoader, compilationDirectory);
    }

    /**
     * <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.");
                }
            }
        }
    }

}
