Java/Development Class/Applet Loader

Материал из Java эксперт
Перейти к: навигация, поиск

Applet Loader Demo

 
import java.applet.Applet;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Hashtable;
import javax.swing.JFrame;
public class MainClass {
  public static void main(String args[]) {
    String name = "http://urlWithClassName";
    try {
      if (!name.endsWith(".class")) {
        System.err.println("That doesn"t look like a byte code file!");
        return;
      }
      URL u = new URL(name);
      URLClassLoader ucl = new URLClassLoader(u);
      // parse out the name of the class from the URL
      String s = u.getFile();
      String classname = s.substring(s.lastIndexOf("/"), s.lastIndexOf(".class"));
      Class AppletClass = ucl.loadClass(classname, true);
      Applet apl = (Applet) AppletClass.newInstance();
      JFrame f = new JFrame();
      f.setSize(200, 200);
      f.add("Center", apl);
      apl.init();
      apl.start();
      f.setVisible(true);
    } catch (Exception e) {
      System.err.println(e);
    }
  }
}
class URLClassLoader extends ClassLoader {
  Hashtable cache = new Hashtable();
  URL url;
  public URLClassLoader(URL u) {
    this.url = u;
  }
  public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
    Class cls = (Class) cache.get(name);
    if (cls == null) {
      try {
        cls = findSystemClass(name);
      } catch (ClassNotFoundException e) {
      }
    }
    if (cls == null) {
      byte classData[] = loadClassData(name);
      cls = defineClass(classData, 0, classData.length);
      cache.put(name, cls);
    }
    if (resolve) {
      resolveClass(cls);
    }
    return cls;
  }
  private byte[] loadClassData(String name) throws ClassNotFoundException {
    byte[] buffer;
    InputStream theClassInputStream = null;
    int bufferLength = 128;
    try {
      URL classURL = new URL(url, name + ".class");
      URLConnection uc = classURL.openConnection();
      uc.setAllowUserInteraction(false);
      try {
        theClassInputStream = uc.getInputStream();
      } catch (NullPointerException e) {
        System.err.println(e);
        throw new ClassNotFoundException(name + " input stream problem");
      }
      int contentLength = uc.getContentLength();
      // A lot of web servers don"t send content-lengths
      // for .class files
      if (contentLength == -1) {
        buffer = new byte[bufferLength * 16];
      } else {
        buffer = new byte[contentLength];
      }
      int bytesRead = 0;
      int offset = 0;
      while (bytesRead >= 0) {
        bytesRead = theClassInputStream.read(buffer, offset, bufferLength);
        if (bytesRead == -1)
          break;
        offset += bytesRead;
        if (contentLength == -1 && offset == buffer.length) { // grow the array
          byte temp[] = new byte[offset * 2];
          System.arraycopy(buffer, 0, temp, 0, offset);
          buffer = temp;
        } else if (offset > buffer.length) {
          throw new ClassNotFoundException(name + " error reading data into the array");
        }
      }
      if (offset < buffer.length) { // shrink the array
        byte temp[] = new byte[offset];
        System.arraycopy(buffer, 0, temp, 0, offset);
        buffer = temp;
      }
      // Make sure all the bytes were received
      if (contentLength != -1 && offset != contentLength) {
        throw new ClassNotFoundException("Only " + offset + " bytes received for " + name
            + "\n Expected " + contentLength + " bytes");
      }
    } catch (Exception e) {
      throw new ClassNotFoundException(name + " " + e);
    } finally {
      try {
        if (theClassInputStream != null)
          theClassInputStream.close();
      } catch (IOException e) {
      }
    }
    return buffer;
  }
}





Dummy Applet Context

   
/**
 * Copyright(c) 1996 DTAI, Incorporated (http://www.dtai.ru)
 *
 *                        All rights reserved
 *
 * Permission to use, copy, modify and distribute this material for
 * any purpose and without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all
 * copies, and that the name of DTAI, Incorporated not be used in
 * advertising or publicity pertaining to this material without the
 * specific, prior written permission of an authorized representative of
 * DTAI, Incorporated.
 *
 * DTAI, INCORPORATED MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES,
 * EXPRESS OR IMPLIED, WITH RESPECT TO THE SOFTWARE, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR ANY PARTICULAR PURPOSE, AND THE WARRANTY AGAINST
 * INFRINGEMENT OF PATENTS OR OTHER INTELLECTUAL PROPERTY RIGHTS.  THE
 * SOFTWARE IS PROVIDED "AS IS", AND IN NO EVENT SHALL DTAI, INCORPORATED OR
 * ANY OF ITS AFFILIATES BE LIABLE FOR ANY DAMAGES, INCLUDING ANY
 * LOST PROFITS OR OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES RELATING
 * TO THE SOFTWARE.
 */
import java.awt.*;
import java.applet.*;
import java.net.*;
import java.util.*;
import java.io.*;
/**
 * DummyAppletContext - implements AppletContext and AppletStub to allow any
 * applet to easily run as an application.  The only thing it can"t do is
 * access URL"s.  Applet parameters are entered on the command line with
 * name as one word and value as the next.
 *
 * @version 1.1
 * @author  DTAI, Incorporated
 *
 * $Id: DummyAppletContext.java,v 1.5 1996/10/08 21:15:09 kadel Exp $
 *
 * $Source: /cvs/java/classes/COM/dtai/gui/DummyAppletContext.java,v $
 */
public class DummyAppletContext
    extends Frame
    implements AppletStub, AppletContext, URLStreamHandlerFactory {
    private TextField status;
    private Hashtable params = new Hashtable();
    private Vector applets = new Vector();
    private int initial_width;
    private int initial_height;
  /**
   * Entry point into the standalone program.
   *
   * @param args  the command line arguments
   */
    public static void main ( String args[] ) {
        new DummyAppletContext( args );
    }
  /**
   * Constructor for the main class, given an existing applet object.
   *
   * @param applet            the applet embedded in this AppletContext
   * @param args              the command line arguments.  Contains possibly
   *                          height and width, and any applet parameters
   */
    public DummyAppletContext( Applet applet, String args[] ) {
        this( applet, 640, 480, args );
    }
  /**
   * Constructor for the main class, given an existing applet object and a default
   * frame (window) width and height.
   *
   * @param applet            the applet embedded in this AppletContext
   * @param default_width     the default width of the window
   * @param default_height    the default width of the window
   * @param args              the command line arguments.  Contains possibly
   *                          height and width, and any applet parameters
   */
    public DummyAppletContext( Applet applet, int default_width, int default_height,
                               String args[] ) {
        super ( applet.getClass().getName() );
        init( applet, default_width, default_height, args, 0 );
    }
  /**
   * Constructor for the main class, from the command line arguments.
   *
   * @param args  the command line arguments.  Contains the name of the applet
   *              class, possibly height and width, and any applet parameters.
   */
    public DummyAppletContext( String args[] ) {
        super ( args[0] );
        try {
            Applet applet = (Applet)Class.forName( args[0] ).newInstance();
            init( applet, 640, 480, args, 1 );
        }
        catch ( Exception e ) {
            e.printStackTrace();
            System.exit( 1 );
        }
    }
  /*
   * PRIVATE initialization function.
   *
   * @param applet            the applet embedded in this AppletContext
   * @param default_width     the default width of the window
   * @param default_height    the default width of the window
   * @param args              the command line arguments.  Contains possibly
   *                          height and width, and any applet parameters
   * @param startidx          index in the args array at which to start parsing
   */
    private void init( Applet applet, int default_width, int default_height,
                       String args[], int startidx ) {
        URL.setURLStreamHandlerFactory( this );
        applets.addElement( applet );
        applet.setStub(this);
        initial_width = default_width;
        initial_height = default_height;
        parseArgs( args, startidx );
        status = new TextField();
        status.setEditable( false );
        add( "Center", applet );
        add( "South", status );
        appletResize( initial_width, initial_height );
        show();
        applet.init();
        applet.start();
    }
  /**
   * Parse the command line arguments.  Get the initial width and height of
   * the window if specified (-width [value] -height [value]), and the
   * applet parameters (name value pairs).
   *
   * @param args              the command line arguments.  Contains possibly
   *                          height and width, and any applet parameters
   * @param startidx          index in the args array at which to start parsing
   */
    public void parseArgs( String args[], int startidx ) {
        for ( int idx = startidx; idx < ( args.length - startidx ); idx+=2 ) {
            try {
                if ( args[idx].equals( "-width" ) ) {
                    initial_width = Integer.parseInt( args[idx+1] );
                }
                else if ( args[idx].equals( "-height" ) ) {
                    initial_height = Integer.parseInt( args[idx+1] );
                }
                else {
                    params.put( args[idx], args[idx+1] );
                }
            }
            catch ( NumberFormatException nfe ) {
                System.err.println("Warning: command line argument "+args[idx]+
                                   " is not a valid number." );
            }
        }
    }
  /**
   * Event handler to catch the Frame (window) close action,
   * and exit the program.
   *
   * @param evt   The event that occurred
   * @return      false if the event was not handled by this object.
   */
    public boolean handleEvent( Event evt ) {
        if ( evt.id == Event.WINDOW_DESTROY ) {
            System.exit(0);
        }
        return super.handleEvent(evt);
    }
/************ AppletStub methods *************/
    /**
     * Returns true if the applet is active.
     *
     * @return  always true
     */
    public boolean isActive() { return true; }
    /**
     * Gets the document URL.
     *
   * @return      a "file:" URL for the current directory
     */
    public URL getDocumentBase() {
        URL url = null;
        try {
            File dummy = new File( "dummy.html" );
            String path = dummy.getAbsolutePath();
            if ( ! File.separator.equals( "/" ) ) {
                StringBuffer buffer = new StringBuffer();
                if ( path.charAt(0) != File.separator.charAt(0) ) {
                    buffer.append( "/" );
                }
                StringTokenizer st = new StringTokenizer( path, File.separator );
                while ( st.hasMoreTokens() ) {
                    buffer.append( st.nextToken() + "/" );
                }
                if ( File.separator.equals( "\\" ) &&
                     ( buffer.charAt(2) == ":" ) ) {
                    buffer.setCharAt( 2, "|" );
                }
                else {
                }
                path = buffer.toString();
                path = path.substring( 0, path.length()-1 );
            }
            url = new URL( "file", "", -1, path );
        }
        catch ( MalformedURLException mue ) {
            mue.printStackTrace();
        }
        return url;
    }
    /**
     * Gets the codebase URL.
     *
   * @return      in this case, the same value as getDocumentBase()
     */
    public final URL getCodeBase() { return getDocumentBase(); }
    /**
     * Gets a parameter of the applet.
     *
   * @param name  the name of the parameter
   * @return      the value, or null if not defined
   */
    public final String getParameter( String name ) {
        return (String)params.get( name );
    }
  /**
   * Gets a handler to the applet"s context.
   *
   * @return  this object
   */
    public final AppletContext getAppletContext() { return this; }
  /**
   * Called when the applet wants to be resized.  This causes the
   * Frame (window) to be resized to accomodate the new Applet size.
   *
   * @param width     the new width of the applet
   * @param height    the new height of the applet
   */
    public void appletResize( int width, int height ) {
        Insets insets = insets();
        resize( ( width + insets.left + insets.right ),
                ( height + status.preferredSize().height +
                  insets.top + insets.bottom ) );
    }
/************ AppletContext methods *************/
  /**
     * Gets an audio clip.  (There doesn"t seem to be a "Toolkit" for
     * audio clips in my JDK, so this always returns null.  You could
     * implement this differently, returning a dummy AudioClip object
     * for which the class could be defined at the bottom of this file.)
   *
   * @param url   URL of the AudioClip to load
   * @return      the AudioClip object if it exists (in our case,
   *              this is always null
   */
    public final AudioClip getAudioClip( URL url ) { return null; }
  /**
     * Gets an image. This usually involves downloading it
     * over the net. However, the environment may decide to
     * cache images. This method takes an array of URLs,
     * each of which will be tried until the image is found.
   *
   * @param url   URL of the Image to load
   * @return      the Image object
   */
    public final Image getImage( URL url ) {
        return Toolkit.getDefaultToolkit().getImage( filenameFromURL( url ) );
    }
  /*
     * PRIVATE utility function.  Ignores the protocol, and returns a
     * filename for a file on the local filesystem (which may or may
     * not exist, of course).
   *
   * @param url   URL to be converted to a filename on the local
   *              filesystem.
   * @return      the filename
   */
    private String filenameFromURL( URL url ) {
        String filename = url.getFile();
        if ( filename.charAt(1) == "|" ) {
            StringBuffer buf = new StringBuffer( filename );
            buf.setCharAt( 1, ":" );
            filename = buf.toString();
        }
        else if ( filename.charAt(2) == "|" ) {
            StringBuffer buf = new StringBuffer( filename );
            buf.setCharAt( 2, ":" );
            filename = buf.toString();
        }
        return filename;
    }
  /**
     * Gets an applet by name.
     *
   * @param name  the name of the applet
     * @return      null if the applet does not exist, and it never
     *              does since we never name the applet.
   */
    public final Applet getApplet( String name ) { return null; }
  /**
     * Enumerates the applets in this context. Only applets
     * that are accessible will be returned. This list always
     * includes the applet itself.
   *
   * @return  the Enumeration -- contains ONLY the applet created with
   *          this DummyAppletContext
   */
    public final Enumeration getApplets() { return applets.elements(); }
  /**
     * Shows a new document. This may be ignored by
     * the applet context (and in our case, it is, but we"ll show the
     * user, in the status area, that the document was requested and
     * WOULD be loaded if in a browser).
   *
   * @param url   URL to load
   */
    public void showDocument( URL url ) {
        status.setText( "AppletContext request to show URL " +
                        url.toString() );
    }
  /**
     * Show a new document in a target window or frame. This may be ignored by
     * the applet context.  (Again, it is ignored, but we"ll show the
     * request information to the user in the status area.)
     *
     * This method accepts the target strings:
     *   _self    show in current frame
     *   _parent  show in parent frame
     *   _top   show in top-most frame
     *   _blank   show in new unnamed top-level window
     *   <other>  show in new top-level window named <other>
   *
   * @param url       URL to load
   * @param target    the target string
   */
    public void showDocument( URL url, String target ) {
        status.setText( "AppletContext request to show URL " +
                        url.toString() +
                        " in target: " + target );
    }
  /**
     * Show a status string in the status area (the Text object at the bottom
     * of the window.
   *
   * @param text  the text to display
   */
    public void showStatus( String text ) { status.setText( text ); }
/************ URLStreamHandlerFactory methods *************/
  /**
     * Creates a new URLStreamHandler instance with the specified protocol.
     *
     * @param protocol  the protocol to use (ftp, http, nntp, etc.).
     *                  THIS PROTOCOL IS IGNORED BY THIS APPLET CONTEXT
     */
    public URLStreamHandler createURLStreamHandler( String protocol ) {
        return new DummyURLStreamHandler();
    }
}
/*
 * A URL stream handler for all protocols, used to return our
 * dummy implementation of URLConnection to open up a local
 * file when called upon.
 */
class DummyURLStreamHandler extends URLStreamHandler {
    protected final URLConnection openConnection( URL u ) throws IOException {
        return new DummyURLConnection( u );
    }
}
/*
 * Our dummy implementation of URLConnection used to open up a local
 * file when called upon with a given URL of ANY protocol type.  This
 * allows the applet to easily use the "getInputStream()" function.
 */
class DummyURLConnection extends URLConnection {
    boolean connected = false;
    InputStream instream;
    /*
     * Constructor for the DummyURLConnection
     */
    protected DummyURLConnection( URL url ) {
        super( url );
    }
    /*
     * open the local file
     */
    public void connect() throws IOException {
        if ( ! connected ) {
            String filename = url.getFile();
            if ( filename.charAt(1) == "|" ) {
                StringBuffer buf = new StringBuffer( filename );
                buf.setCharAt( 1, ":" );
                filename = buf.toString();
            }
            else if ( filename.charAt(2) == "|" ) {
                StringBuffer buf = new StringBuffer( filename );
                buf.setCharAt( 2, ":" );
                filename = buf.toString();
            }
            instream = new FileInputStream( filename );
        }
    }
    /*
     * return the open stream to the local file (open if necessary).
     */
    public InputStream getInputStream() throws IOException {
        if ( ! connected ) {
            connect();
        }
        if ( instream == null ) {
            throw new IOException();
        }
        return instream;
    }
}