import java.io.InputStream;
import java.io.IOException;
import java.net.URL;

/**
 * An object that is responsible for loading classes from an
 * HTTP server.
 *
 * @version 1.0
 * @author  Prof. David Bernstein, James Madison University
 */
public class HTTPClassLoader extends ClassLoader 
{

    private String      uri;

    public static final String EXT = ".class";


    /**
     * Explicit Value Constructor
     * 
     * @param uri   The host and path to load from
     */
    public HTTPClassLoader(String uri)
    {
       this.uri = uri;
    }

    /**
     * Finds the class with the specified name
     *
     * @param name    The name of the class (without extension)
     * @return        The resulting Class object
     */
    protected Class findClass(String name) throws ClassNotFoundException
    {
       byte[]         bytes;
       Class          c;

       bytes = null;
       try 
       {
          bytes = requestBytes(name);
          c = defineClass(name, bytes, 0, bytes.length);
          if (c == null) throw new ClassNotFoundException(name);
       } 
       catch (IOException ioe) 
       {
          throw new ClassNotFoundException(name);
       }

       return c;
    }

    /**
     * Request the bytes in the class using an HTTP GET request
     *
     * @param name  The name of the class (without the extension)
     * @param       The bytes that comprise the class
     */
    private byte[] requestBytes(String name) throws IOException
    {
       byte[]         bytes;
       InputStream    in;
       URL            u;


       u = new URL(uri + name + EXT);
        
       in    = u.openStream();
       bytes = new byte[in.available()];

       in.read(bytes);
        
       return bytes;
    }
}
