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