/*
 [The "BSD licence"]
 Copyright (c) 2009 Shaoting Cai
 All rights reserved.

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
    notice, this list of conditions and the following disclaimer in the
    documentation and/or other materials provided with the distribution.
 3. The name of the author may not be used to endorse or promote products
    derived from this software without specific prior written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.gunit.swingui.runner;

import java.io.*;
import java.util.HashMap;

/**
 * Class loader for parser & lexer generated by antlr.
 * @author Shaoting
 */
public class ParserLoader extends ClassLoader {

    private HashMap<String, Class> classList;
    private String grammar;

    /**
     * Create a class loader for antlr parser/lexer.
     * @param grammarName
     * @param classDir
     */
    public ParserLoader(String grammarName, String classDir) throws IOException, ClassNotFoundException {

        final String lexerName = grammarName + "Lexer";

        // load all the class files in the "classDir" related to the grammarName
        File dir = new File(classDir);
        if(dir.isDirectory()) {
            classList = new HashMap<String, Class>();
            grammar = grammarName;
            File[] files = dir.listFiles(new ClassFilenameFilter(grammarName));
            for(File f : files) {

                // load class data
                final InputStream in = new BufferedInputStream(new FileInputStream(f));
                final byte[] classData = new byte[in.available()];
                in.read(classData);
                in.close();

                // define class
                final Class newClass = defineClass(null, classData, 0, classData.length);
                assert(newClass != null);
                resolveClass(newClass);

                // save to hashtable
                final String fileName = f.getName();
                final String className = fileName.substring(0, fileName.lastIndexOf("."));
                classList.put(className, newClass);
                //System.out.println("adding: " + className);
            }
        } else {
            throw new IOException(classDir + " is not a directory.");
        }

        if(classList.isEmpty() || !classList.containsKey(lexerName)) {
            throw new ClassNotFoundException(lexerName + " not found.");
        }

    }



    @Override
    public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
        //System.out.print("loading: " + name);
        if(name.startsWith(grammar)) {
            if(classList.containsKey(name)) {
                //System.out.println(" .... found");
                return classList.get(name);
            } else {
                //System.out.println(" .... not found");
                throw new ClassNotFoundException(name);
            }
            
        } else {
            final Class c = findSystemClass(name);
            //System.out.println(" .... system found " + c.getName());
            return c;
        }
    }

    /**
     * Accepts grammarname...($...)?.class
     */
    protected static class ClassFilenameFilter implements FilenameFilter {

        private String grammarName;

        protected ClassFilenameFilter(String name) {
            grammarName = name;
        }

        public boolean accept(File dir, String name) {
            return name.startsWith(grammarName) && name.endsWith(".class");
        }

    }

}
