1/* 2 * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26/* 27 * Licensed Materials - Property of IBM 28 * RMI-IIOP v1.0 29 * Copyright IBM Corp. 1998 1999 All Rights Reserved 30 * 31 */ 32 33package sun.rmi.rmic.iiop; 34 35import java.util.Hashtable; 36import java.io.File; 37import java.io.FileInputStream; 38 39/** 40 * DirectoryLoader is a simple ClassLoader which loads from a specified 41 * file system directory. 42 * @author Bryan Atsatt 43 */ 44 45public class DirectoryLoader extends ClassLoader { 46 47 private Hashtable cache; 48 private File root; 49 50 /** 51 * Constructor. 52 */ 53 public DirectoryLoader (File rootDir) { 54 cache = new Hashtable(); 55 if (rootDir == null || !rootDir.isDirectory()) { 56 throw new IllegalArgumentException(); 57 } 58 root = rootDir; 59 } 60 61 private DirectoryLoader () {} 62 63 /** 64 * Convenience version of loadClass which sets 'resolve' == true. 65 */ 66 public Class loadClass(String className) throws ClassNotFoundException { 67 return loadClass(className, true); 68 } 69 70 /** 71 * This is the required version of loadClass which is called 72 * both from loadClass above and from the internal function 73 * FindClassFromClass. 74 */ 75 public synchronized Class loadClass(String className, boolean resolve) 76 throws ClassNotFoundException { 77 Class result; 78 byte classData[]; 79 80 // Do we already have it in the cache? 81 82 result = (Class) cache.get(className); 83 84 if (result == null) { 85 86 // Nope, can we get if from the system class loader? 87 88 try { 89 90 result = super.findSystemClass(className); 91 92 } catch (ClassNotFoundException e) { 93 94 // No, so try loading it... 95 96 classData = getClassFileData(className); 97 98 if (classData == null) { 99 throw new ClassNotFoundException(); 100 } 101 102 // Parse the class file data... 103 104 result = defineClass(classData, 0, classData.length); 105 106 if (result == null) { 107 throw new ClassFormatError(); 108 } 109 110 // Resolve it... 111 112 if (resolve) resolveClass(result); 113 114 // Add to cache... 115 116 cache.put(className, result); 117 } 118 } 119 120 return result; 121 } 122 123 /** 124 * Reurn a byte array containing the contents of the class file. Returns null 125 * if an exception occurs. 126 */ 127 private byte[] getClassFileData (String className) { 128 129 byte result[] = null; 130 FileInputStream stream = null; 131 132 // Get the file... 133 134 File classFile = new File(root,className.replace('.',File.separatorChar) + ".class"); 135 136 // Now get the bits... 137 138 try { 139 stream = new FileInputStream(classFile); 140 result = new byte[stream.available()]; 141 stream.read(result); 142 } catch(ThreadDeath death) { 143 throw death; 144 } catch (Throwable e) { 145 } 146 147 finally { 148 if (stream != null) { 149 try { 150 stream.close(); 151 } catch(ThreadDeath death) { 152 throw death; 153 } catch (Throwable e) { 154 } 155 } 156 } 157 158 return result; 159 } 160} 161