001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021package org.biojava.utils.bytecode;
022
023import java.io.*;
024import java.util.*;
025
026/**
027 * A class loader that actually produces real Java classes from
028 * GeneratedCodeClass instances.
029 *
030 * @author Thomas Down
031 * @author Matthew Pocock
032 */
033public class GeneratedClassLoader extends ClassLoader {
034  private Set generatedClasses = new HashSet();
035
036  /**
037   * Create a new loader with the default parent.
038   */
039  public GeneratedClassLoader() {
040    super();
041  }
042
043  /**
044   * Create a new loader with an explicitly set parent class loader.
045   *
046   * @param parent  the parent ClassLoader
047   */
048  public GeneratedClassLoader(ClassLoader parent) {
049    super(parent);
050  }
051
052  /**
053   * Define a class based upon a GeneratedCodeClass.
054   *
055   * @param cc  the GeneratedCodeClass to define
056   * @return    the newly defined class
057   * @throws CodeException  if there was a failure defining the class
058   */
059  public Class defineClass(GeneratedCodeClass cc) throws CodeException {
060    try {
061            ByteArrayOutputStream bos = new ByteArrayOutputStream();
062            cc.createCode(bos);
063            byte[] code = bos.toByteArray();
064      Class clazz = defineClass(cc.getName(), code, 0, code.length);
065      generatedClasses.add(clazz.getName());
066      return clazz;
067    } catch (IOException ex) {
068            // Seems unlikely...
069            throw new CodeException();
070    }
071  }
072
073  /**
074   * Discover if a class for this name has already been defined by this class
075   * loader.
076   *
077   * @param name  the name of the class
078   * @return      true if the class has already been defined by this loader
079   */
080  public boolean hasGeneratedClass(String name) {
081    return generatedClasses.contains(name);
082  }
083}