Package net.xoetrope.optional.resources

Source Code of net.xoetrope.optional.resources.XRemoteClassLoader

package net.xoetrope.optional.resources;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import net.xoetrope.xui.build.BuildProperties;
import net.xoetrope.debug.DebugLogger;
import java.net.URLConnection;
import net.xoetrope.xui.XProject;

/**
* Used to locate project files. It searches for files within the paths
* specified in the paths array.
* The paths/URIs can be specified in the startup file as follows:<br>
* NumRemoteClassLoaderPaths=2<br>
* RemoteClassLoaderPath1=http://localhost:8080/<br>
* RemoteClassLoaderPath2=http://localhost:8080/myresources/<br>
* <p>Copyright: Copyright (c) Xoetrope Ltd., 1998-2003</p>
* $Revision: 2.3 $
*/
public class XRemoteClassLoader extends ClassLoader implements XResourceLoader
{
  /**
   * the URIs that are searched
   */
  protected URI[] uri;

  /**
   * Create a new class loader. Initially no search path is set.
   * @param the owner project
   */
  public XRemoteClassLoader( XProject project )
  {
    super();

    try {
      XProject currentProject = project;
      int numClassLoadersPaths = new Integer( currentProject.getStartupParam( "NumRemoteClassLoaderPaths" ) ).intValue();
      String paths[] = new String[ numClassLoadersPaths ];
      for ( int i = 0; i < numClassLoadersPaths; i++ )
        paths[ i ] = currentProject.getStartupParam( "RemoteClassLoaderPath" + ( i + 1 ));
      setSources( paths );
    }
    catch ( Exception e ) {
      if ( BuildProperties.DEBUG )
        DebugLogger.logError( "Unable to load class loader: " + e.getMessage() );
      else
        System.err.println( e.getMessage() );
    }
  }

  /**
   * Set the URIs for loading files
   * @param projectUris The String array of URLs for inclusion in the search.
   * @return true on success, false if there were problems.
   */
  public boolean setSources( String[] projectUris )
  {
    try {
      uri = new URI[ projectUris.length ];
      for ( int i = 0; i < projectUris.length; i++ ) {
        uri[ i ] = new URI( projectUris[ i ] );
      }
    }
    catch ( URISyntaxException ex ) {
      ex.printStackTrace();
      return false;
    }

    return true;
  }

  /**
   * Overrides the Classloader method and searches for the resource file
   * specifies by the parameter fileName.
   * @param fileName The name of the file to be found.
   * @return An InputStream created by from the filename if found or null if not
   * found.
   */
  public InputStream getResourceAsStream( String fileName )
  {
    try {
      for ( int i = 0; i < uri.length; i++ ) {
        URL url = new URL( uri[ i ].toURL(), fileName );
        URLConnection conn = url.openConnection();
        conn.setDefaultUseCaches( false );
        conn.setDoOutput( true );
        conn.setIfModifiedSince( 0 );

        InputStream is = conn.getInputStream();
        if ( is != null )
          return is;
      }
    }
    catch ( IOException ex ) {
    }

    return null;
  }

  /**
   * Overrides the Classloader method and searches for the resource file
   * specifies by the parameter fileName.
   * @param fileName The name of the file to be found.
   * @return A URL from the filename if found or null if not
   * found.
   */
  public URL findResource( String fileName )
  {
    try {
      for ( int i = 0; i < uri.length; i++ ) {
        String prefix = ( fileName.indexOf( "\\" ) > -1 || fileName.indexOf( "/" ) > -1 ) ? "" : uri[ i ].toString() + File.separatorChar;
        File f = new File( prefix + fileName );
        if ( f.exists() ) {
          return f.toURL();
        }
      }
    }
    catch ( MalformedURLException ex ) {
    }
    catch ( NullPointerException ex ) {
    }
    return null;
  }

  /**
   * Finds the specified class. This method should be overridden
   * by class loader implementations that follow the new delegation model
   * for loading classes, and will be called by the <code>loadClass</code>
   * method after checking the parent class loader for the requested class.
   * The default implementation throws <code>ClassNotFoundException</code>.
   * @return the resulting <code>Class</code> object
   * @param className the class to locate
   * @exception ClassNotFoundException if the class could not be found
   */
  public Class findClass( String className ) throws ClassNotFoundException
  {
    return ( findClass( className, true ) );
  }

  /**
   * Overrides the method from ClassLoader. This method is called auotmatically
   * if the system classloader cannot find the class it is looking for. We then
   * have the chance to find, load and return the class.
   * @param className The name of the class we are being asked to find
   * @param resolveIt Simply forward the value passed in
   * @return The newly created Class
   * @throws ClassNotFoundException pronlems...
   */
  public synchronized Class findClass( String className, boolean resolveIt ) throws ClassNotFoundException
  {
    Class result;
    byte[] classBytes;

    try {
      result = super.findSystemClass( className );
      return result;
    }
    catch ( ClassNotFoundException e ) {
    }

    classBytes = loadClassBytes( className );
    if ( classBytes == null ) {
      throw new ClassNotFoundException();
    }
    // Define it (parse the class file)
    result = defineClass( classBytes, 0, classBytes.length );
    if ( result == null ) {
      throw new ClassFormatError();
    }
    // Resolve if necessary
    if ( resolveIt )
      resolveClass( result );

    // Done
    return result;
  }

  /**
   * Opens the class file specified by the className. If found it opens the file
   * and loads it into a byte array. The byte array is then returned.
   * @param className The name of the class we are being asked to load
   * @return A byte array created from the class file.
   */
  private byte[] loadClassBytes( String className )
  {
    byte[] classBytes = new byte[ 0 ];
    InputStream is = getResourceAsStream( className + ".class" );
    try {
      byte[] b = new byte[ 1000 ];
      int i = is.read( b );
      while ( i != -1 ) {
        byte[] tempBytes = classBytes;
        classBytes = new byte[ classBytes.length + i ];
        System.arraycopy( b, 0, classBytes, tempBytes.length, i );
        b = new byte[ 1000 ];
        i = is.read( b );
      }
    }
    catch ( IOException ex ) {
    }
    return classBytes;
  }
}
TOP

Related Classes of net.xoetrope.optional.resources.XRemoteClassLoader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.