Package net.janino

Source Code of net.janino.JavaSourceIClassLoader

/*
* Janino - An embedded Java[TM] compiler
* Copyright (C) 2001-2004 Arno Unkrig
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Contact information:
*   Arno Unkrig
*   Ferdinand-Miller-Platz 10
*   80335 Muenchen
*   Germany
*   http://www.janino.net
*   maintainer@janino.net
*/

package net.janino;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.Set;

import net.janino.util.ClassFile;
import net.janino.util.TunnelException;
import net.janino.util.resource.ResourceFinder;

/**
* This {@link net.janino.IClassLoader} finds, scans and parses compilation units.
* <p>
* Notice that it does not compile them!
*/
final class JavaSourceIClassLoader extends IClassLoader {
    private static final boolean DEBUG = false;

    private final ResourceFinder sourceFinder;
    private final String         optionalCharacterEncoding;
    private final Set            uncompiledCompilationUnits; // Java.CompilationUnit

    /**
     * Notice that the <code>uncompiledCompilationUnits</code> set is both read and written
     * by the {@link JavaSourceIClassLoader}: As it searches for {@link IClass}es, it looks
     * into <code>uncompiledCompilationUnits</code> for class declarations, and as it opens,
     * scans and parses compilation units on-the-fly, it adds them to
     * <code>uncompiledCompilationUnits</code>.
     */
    public JavaSourceIClassLoader(
        ResourceFinder sourceFinder,
        String         optionalCharacterEncoding,
        Set            uncompiledCompilationUnits,
        IClassLoader   optionalParentIClassLoader
    ) {
        super(optionalParentIClassLoader);

        this.sourceFinder               = sourceFinder;
        this.optionalCharacterEncoding  = optionalCharacterEncoding;
        this.uncompiledCompilationUnits = uncompiledCompilationUnits;
        super.postConstruct();
    }

    /**
     * @param type field descriptor of the {@IClass} to load, e.g. "Lpkg1/pkg2/Outer$Inner;"
     * @throws TunnelException wraps a {@link Scanner.ScanException}
     * @throws TunnelException wraps a {@link Parser.ParseException}
     * @throws TunnelException wraps a {@link IOException}
     */
    public IClass findIClass(final String type) {
        if (JavaSourceIClassLoader.DEBUG) System.out.println("type = " + type);
   
        // Class type.
        String className = Descriptor.toClassName(type); // E.g. "pkg1.pkg2.Outer$Inner"
        if (JavaSourceIClassLoader.DEBUG) System.out.println("2 className = \"" + className + "\"");
   
        // Do not attempt to load classes from package "java".
        if (className.startsWith("java.")) return null;
   
        // Check the already-parsed compilation units.
        for (Iterator it = this.uncompiledCompilationUnits.iterator(); it.hasNext();) {
            Java.CompilationUnit cu = (Java.CompilationUnit) it.next();
            IClass res = cu.findClass(className);
            if (res != null) {
                this.defineIClass(res);
                return res;
            }
        }

        try {

            // Find source file.
            URL sourceURL = this.sourceFinder.findResource(ClassFile.getSourceResourceName(className));
            if (sourceURL == null) return null;
            if (JavaSourceIClassLoader.DEBUG) System.out.println("sourceURL=" + sourceURL);

            // Scan and parse the source file.
            Java.CompilationUnit cu;
            InputStream inputStream = sourceURL.openStream();
            try {
                Scanner scanner = new Scanner(sourceURL.getFile(), inputStream, this.optionalCharacterEncoding);
                Parser parser = new Parser(scanner);
                cu = parser.parseCompilationUnit();
            } finally {
                try { inputStream.close(); } catch (IOException ex) {}
            }

            // Remember compilation unit for later compilation.
            this.uncompiledCompilationUnits.add(cu);

            // Find the class/interface declaration in the com
            IClass res = cu.findClass(className);
            if (res == null) throw new Parser.ParseException("Source file \"" + sourceURL.getFile() + "\" does not declare class \"" + className + "\"", (Scanner.Location) null);
            this.defineIClass(res);
            return res;
        } catch (Scanner.ScanException e) {
            throw new TunnelException(e);
        } catch (Parser.ParseException e) {
            throw new TunnelException(e);
        } catch (IOException e) {
            throw new TunnelException(e);
        }
    }
}
TOP

Related Classes of net.janino.JavaSourceIClassLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.