package junit.runner;

import java.util.*;
import java.io.*;
import java.net.URL;
import java.util.zip.*;

/**
 * A custom class loader which enables the reloading
 * of classes for each test run. The class loader
 * can be configured with a list of package paths that
 * should be excluded from loading. The loading
 * of these packages is delegated to the system class
 * loader. They will be shared across test runs.
 * <p>
 * The list of excluded package paths is specified in
 * a properties file "excluded.properties" that is located in
 * the same place as the TestCaseClassLoader class.
 * <p>
 * <b>Known limitation:</b> the TestCaseClassLoader cannot load classes
 * from jar files.
 * {@hide} - Not needed for 1.0 SDK
 */
public class TestCaseClassLoader extends ClassLoader {
    /** scanned class path */
    private Vector fPathItems;
    /** default excluded paths */
    private String[] defaultExclusions= {
            "junit.framework.",
            "junit.extensions.",
            "junit.runner."
    };
    /** name of excluded properties file */
    static final String EXCLUDED_FILE= "excluded.properties";
    /** excluded paths */
    private Vector fExcluded;

    /**
     * Constructs a TestCaseLoader. It scans the class path
     * and the excluded package paths
     */
    public TestCaseClassLoader() {
        this(System.getProperty("java.class.path"));
    }

    /**
     * Constructs a TestCaseLoader. It scans the class path
     * and the excluded package paths
     */
    public TestCaseClassLoader(String classPath) {
        scanPath(classPath);
        readExcludedPackages();
    }

    private void scanPath(String classPath) {
        String separator= System.getProperty("path.separator");
        fPathItems= new Vector(10);
        StringTokenizer st= new StringTokenizer(classPath, separator);
        while (st.hasMoreTokens()) {
            fPathItems.addElement(st.nextToken());
        }
    }

    public URL getResource(String name) {
        return ClassLoader.getSystemResource(name);
    }

    public InputStream getResourceAsStream(String name) {
        return ClassLoader.getSystemResourceAsStream(name);
    }

    public boolean isExcluded(String name) {
        for (int i= 0; i < fExcluded.size(); i++) {
            if (name.startsWith((String) fExcluded.elementAt(i))) {
                return true;
            }
        }
        return false;
    }

    public synchronized Class loadClass(String name, boolean resolve)
            throws ClassNotFoundException {

        Class c= findLoadedClass(name);
        if (c != null)
            return c;
        //
        // Delegate the loading of excluded classes to the
        // standard class loader.
        //
        if (isExcluded(name)) {
            try {
                c= findSystemClass(name);
                return c;
            } catch (ClassNotFoundException e) {
                // keep searching
            }
        }
        if (c == null) {
            byte[] data= lookupClassData(name);
            if (data == null)
                throw new ClassNotFoundException();
            c= defineClass(name, data, 0, data.length);
        }
        if (resolve)
            resolveClass(c);
        return c;
    }

    private byte[] lookupClassData(String className) throws ClassNotFoundException {
        byte[] data= null;
        for (int i= 0; i < fPathItems.size(); i++) {
            String path= (String) fPathItems.elementAt(i);
            String fileName= className.replace('.', '/')+".class";
            if (isJar(path)) {
                data= loadJarData(path, fileName);
            } else {
                data= loadFileData(path, fileName);
            }
            if (data != null)
                return data;
        }
        throw new ClassNotFoundException(className);
    }

    boolean isJar(String pathEntry) {
        return pathEntry.endsWith(".jar") ||
                pathEntry.endsWith(".apk") ||
                pathEntry.endsWith(".zip");
    }

    private byte[] loadFileData(String path, String fileName) {
        File file= new File(path, fileName);
        if (file.exists()) {
            return getClassData(file);
        }
        return null;
    }

    private byte[] getClassData(File f) {
        try {
            FileInputStream stream= new FileInputStream(f);
            ByteArrayOutputStream out= new ByteArrayOutputStream(1000);
            byte[] b= new byte[1000];
            int n;
            while ((n= stream.read(b)) != -1)
                out.write(b, 0, n);
            stream.close();
            out.close();
            return out.toByteArray();

        } catch (IOException e) {
        }
        return null;
    }

    private byte[] loadJarData(String path, String fileName) {
        ZipFile zipFile= null;
        InputStream stream= null;
        File archive= new File(path);
        if (!archive.exists())
            return null;
        try {
            zipFile= new ZipFile(archive);
        } catch(IOException io) {
            return null;
        }
        ZipEntry entry= zipFile.getEntry(fileName);
        if (entry == null)
            return null;
        int size= (int) entry.getSize();
        try {
            stream= zipFile.getInputStream(entry);
            byte[] data= new byte[size];
            int pos= 0;
            while (pos < size) {
                int n= stream.read(data, pos, data.length - pos);
                pos += n;
            }
            zipFile.close();
            return data;
        } catch (IOException e) {
        } finally {
            try {
                if (stream != null)
                    stream.close();
            } catch (IOException e) {
            }
        }
        return null;
    }

    private void readExcludedPackages() {
        fExcluded= new Vector(10);
        for (int i= 0; i < defaultExclusions.length; i++)
            fExcluded.addElement(defaultExclusions[i]);

        InputStream is= getClass().getResourceAsStream(EXCLUDED_FILE);
        if (is == null)
            return;
        Properties p= new Properties();
        try {
            p.load(is);
        }
        catch (IOException e) {
            return;
        } finally {
            try {
                is.close();
            } catch (IOException e) {
            }
        }
        for (Enumeration e= p.propertyNames(); e.hasMoreElements(); ) {
            String key= (String)e.nextElement();
            if (key.startsWith("excluded.")) {
                String path= p.getProperty(key);
                path= path.trim();
                if (path.endsWith("*"))
                    path= path.substring(0, path.length()-1);
                if (path.length() > 0)
                    fExcluded.addElement(path);
            }
        }
    }
}
