001    package 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     */
009    public 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    }