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     */
021    package org.biojava.utils.bytecode;
022    
023    import java.io.*;
024    import 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     */
033    public 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    }