001 package com.croftsoft.core.lang.classloader;
002
003 /*********************************************************************
004 * <P>
005 * Assumes that Java 1.1 is being used and classes are cached as the
006 * default behavior as part of the defineClass() method.
007 * <P>
008 * This should be upgraded when the switch is made from Java 1.1 to
009 * Java 1.2.
010 * <P>
011 * <B>
012 * References
013 * </B>
014 * Scott Oaks, <U>Java Security</U>, O'Reilly, 1998.
015 * <P>
016 * @version
017 * 1998-05-25
018 * @author
019 * <a href="https://www.croftsoft.com/">David Wallace Croft</a>
020 *********************************************************************/
021
022 public abstract class CustomClassLoader extends ClassLoader
023 //////////////////////////////////////////////////////////////////////
024 //////////////////////////////////////////////////////////////////////
025 {
026
027 /*********************************************************************
028 * Parses the package name out of a full class name.
029 * Returns the empty string ("") if the class is not in a package.
030 *********************************************************************/
031 public static String parsePackageName ( String className )
032 //////////////////////////////////////////////////////////////////////
033 {
034 String packageName = "";
035 int i = className.lastIndexOf ( '.' );
036 if ( i > -1 ) packageName = className.substring ( 0, i );
037 return packageName;
038 }
039
040 /*********************************************************************
041 * Returns the Class of the given name.
042 * <P>
043 * Calls loadClassData() if the class was not previously loaded and
044 * is not a system class.
045 *********************************************************************/
046 public Class loadClass ( String name, boolean resolve )
047 //////////////////////////////////////////////////////////////////////
048 // See Ch. 3, "Java Class Loaders", "Implementing a Class Loader",
049 // pp44-45.
050 //////////////////////////////////////////////////////////////////////
051 {
052 // Step 1 -- Check for a previously loaded class
053 Class c = findLoadedClass ( name );
054 if ( c != null ) return c;
055
056 // Step 2 -- Check to make sure that we can access this class
057 String packageName = null;
058 SecurityManager securityManager = System.getSecurityManager ( );
059 if ( securityManager != null )
060 {
061 packageName = parsePackageName ( name );
062 // What if in "default" package?
063 securityManager.checkPackageAccess ( packageName );
064 }
065
066 // Step 3 -- Check for system class first
067 try
068 {
069 c = findSystemClass ( name );
070 if ( c != null ) return c;
071 }
072 catch ( ClassNotFoundException ex ) { }
073
074 // Step 4 -- Check to make sure that we can define this class
075 if ( securityManager != null )
076 {
077 securityManager.checkPackageDefinition ( packageName );
078 }
079
080 // Step 5 -- Read in the class file
081 byte [ ] data = loadClassData ( name );
082 if ( data == null ) return null;
083
084 // Step 6 and 7 -- Define the class from the data;
085 // this also passes the data through the bytecode verifier
086 c = defineClass ( name, data, 0, data.length );
087
088 // Step 8 -- Resolve the internal references of the class
089 if ( resolve ) resolveClass ( c );
090
091 return c;
092 }
093
094 /*********************************************************************
095 * Implement to load the raw bytecode from an external source.
096 * @return
097 * May return null on failure.
098 *********************************************************************/
099 // Better to thrown an exception than to return null.
100 protected abstract byte [ ] loadClassData ( String name );
101
102 /*********************************************************************
103 * Calls getSystemResource(name).
104 *********************************************************************/
105 /*
106 public URL getResource ( String name )
107 //////////////////////////////////////////////////////////////////////
108 {
109 return getSystemResource ( name );
110 }
111 */
112
113 /*********************************************************************
114 * Calls getSystemResourceAsStream(name).
115 *********************************************************************/
116 /*
117 public InputStream getResourceAsStream ( String name )
118 //////////////////////////////////////////////////////////////////////
119 {
120 return getSystemResourceAsStream ( name );
121 }
122 */
123
124 //////////////////////////////////////////////////////////////////////
125 //////////////////////////////////////////////////////////////////////
126 }