/*******************************************************************************
* Copyright (c)                                                                *
*           2005   Tristan Allwood,                                            *
*           2005   Daniel Burke,                                               *
*           2005   Marc Hull,                                                  *
*           2005   Ekaterina Itskova,                                          *
*           2005   Steve Zymler                                                *
*                                                                              *
* Permission is hereby granted, free of charge, to any person obtaining a      *
* copy of this software and associated documentation files (the                *
* "Software"), to deal in the Software without restriction, including          *
* without limitation the rights to use, copy, modify, merge, publish,          *
* distribute, sublicense, and/or sell copies of the Software, and to           *
* permit persons to whom the Software is furnished to do so, subject to        *
* the following conditions:                                                    *
*                                                                              *
* The above copyright notice and this permission notice shall be included      *
* in all copies or substantial portions of the Software.                       *
*                                                                              *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS      *
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF                   *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.       *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY         *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,         *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE            *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                       *
*******************************************************************************/
/*
 * Created on 22-Oct-2004 by toa02
 *
 */
package uk.ac.ic.doc.kevlar.core.framework.internal.loaders;

import java.io.File;
import java.util.HashSet;
import java.util.Set;

import uk.ac.ic.doc.kevlar.core.framework.internal.loaders.util.FrameworkClassLoader;
import uk.ac.ic.doc.kevlar.core.framework.internal.loaders.util.RestrictedClassLoader;
import uk.ac.ic.doc.kevlar.publicInterfaces.IType;

/**
 * @author toa02
 *  
 */
public class LoaderProvider {

    private static ILoader instance;

    /**
     * Provides access to the Framework singleton loader. If we need to be able
     * to create multiple loaders, then this will be upgraded at that point.
     * 
     * @return The system ILoader.
     */
    public synchronized static ILoader getLoader() {
        return getLoader(IType.class.getClassLoader());
    }

    /**
     * Provides access to the singleton loader, <b>for use with JUnit tests</b> when an
     * explicit overriding of the classloader needs to take place. If this
     * method is called when the instance has already been set up, then the
     * classloader is ignored.
     * 
     * @param parent
     *            The ClassLoader parent to use for the loader. Ignored if the
     *            ILoader has been set up already.
     * @return An ILoader instance.
     */
    public synchronized static ILoader getLoader(ClassLoader parent) {
        if (instance == null) {

            /* construct the default directories and stuff */
            String typeDirs = System.getProperty(ILoader.TYPES, ILoader.TYPES
                    + File.pathSeparatorChar + "lib" + File.separatorChar
                    + ILoader.TYPES);
            String progDirs = System.getProperty(ILoader.PROGRAMS,
                    ILoader.PROGRAMS + File.pathSeparatorChar + "lib"
                            + File.separatorChar + ILoader.PROGRAMS);

            /* lets create a set of directories: */
            Set<File> typeDs = new HashSet<File>();

            Set<File> progDs = new HashSet<File>();

            for (String cs : typeDirs.split("" + File.pathSeparatorChar)) {
                File f = new File(cs);
                if (f.canRead() && f.isDirectory()) {
                    typeDs.add(f);
                }
            }

            for (String cs : progDirs.split("" + File.pathSeparatorChar)) {
                File f = new File(cs);
                if (f.canRead() && f.isDirectory()) {
                    progDs.add(f);
                }
            }

            FrameworkClassLoader fcl = new FrameworkClassLoader(new RestrictedClassLoader(parent));

            instance = new Loader(typeDs, progDs, fcl);
        }

        return instance;
    }
}
