001package serp.bytecode;
002
003/**
004 * Class loader that will attempt to find requested classes in a given
005 * {@link Project}.
006 *
007 * @author Abe White
008 */
009public class BCClassLoader extends ClassLoader {
010    private Project _project = null;
011
012    /**
013     * Constructor. Supply the project to use when looking for classes.
014     */
015    public BCClassLoader(Project project) {
016        _project = project;
017    }
018
019    /**
020     * Constructor. Supply the project to use when looking for classes.
021     *
022     * @param parent the parent classoader
023     */
024    public BCClassLoader(Project project, ClassLoader loader) {
025        super(loader);
026        _project = project;
027    }
028
029    /**
030     * Return this class loader's project.
031     */
032    public Project getProject() {
033        return _project;
034    }
035
036    protected Class findClass(String name) throws ClassNotFoundException {
037        byte[] bytes;
038        try {
039            BCClass type;
040            if (!_project.containsClass(name))
041                type = createClass(name);
042            else
043                type = _project.loadClass(name);
044            if (type == null)
045                throw new ClassNotFoundException(name);
046            bytes = type.toByteArray();
047        } catch (RuntimeException re) {
048            throw new ClassNotFoundException(re.toString());
049        }
050        return defineClass(name, bytes, 0, bytes.length);
051    }
052
053    /**
054     * Override this method if unfound classes should be created on-the-fly.
055     * Returns null by default.
056     */
057    protected BCClass createClass(String name) {
058        return null;
059    }
060}