00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.objectweb.cjdbc.controller.connection;
00026
00027 import java.io.BufferedInputStream;
00028 import java.io.File;
00029 import java.io.FileInputStream;
00030 import java.io.FilenameFilter;
00031 import java.io.IOException;
00032 import java.net.MalformedURLException;
00033 import java.net.URL;
00034 import java.util.Enumeration;
00035 import java.util.Hashtable;
00036 import java.util.jar.JarFile;
00037 import java.util.zip.ZipEntry;
00038 import java.util.zip.ZipFile;
00039 import java.util.zip.ZipInputStream;
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 public class DriverClassLoader extends ClassLoader
00058 {
00059
00060
00061 private File path = null;
00062
00063
00064
00065
00066
00067
00068
00069 DriverClassLoader(ClassLoader parent, File pPath)
00070 {
00071 super(parent);
00072 path = pPath;
00073 if (path == null)
00074 path = new File("");
00075
00076 }
00077
00078
00079
00080
00081
00082
00083 protected Class findClass(String className) throws ClassNotFoundException
00084 {
00085
00086 FileInputStream fis = null;
00087
00088 try
00089 {
00090 byte[] classBytes = null;
00091
00092
00093 String pathName = className.replace('.', File.separatorChar);
00094 File file = new File(path.getAbsolutePath(), pathName + ".class");
00095 if (file.exists())
00096 {
00097
00098 fis = new FileInputStream(file);
00099 classBytes = new byte[fis.available()];
00100 fis.read(classBytes);
00101 }
00102 else
00103 {
00104
00105 classBytes = findClassInJarFile(path, className);
00106 }
00107
00108
00109 Class clazz = defineClass(null, classBytes, 0, classBytes.length);
00110 return clazz;
00111 }
00112 catch (Exception e)
00113 {
00114
00115 throw new ClassNotFoundException(className, e);
00116 }
00117 finally
00118 {
00119 if (null != fis)
00120 {
00121 try
00122 {
00123 fis.close();
00124 }
00125 catch (Exception e)
00126 {
00127 }
00128 }
00129 }
00130 }
00131
00132
00133
00134
00135
00136 private Hashtable htJarContents = new Hashtable();
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 private byte[] findClassInJarFile(File dir, String className)
00147 throws IOException
00148 {
00149
00150 String resourceName = convertClassNameToResourceName(className);
00151 byte[] classBytes = (byte[]) htJarContents.get(resourceName);
00152 if (classBytes != null)
00153 {
00154
00155 return classBytes;
00156 }
00157
00158 if (!dir.canRead())
00159 throw new IOException(dir + " is not readable.");
00160
00161 if (dir.isFile())
00162 {
00163
00164 loadJarFile(dir.getAbsolutePath());
00165
00166 return (byte[]) htJarContents.get(resourceName);
00167 }
00168
00169
00170
00171
00172 String[] jarFiles = dir.list(new FilenameFilter()
00173 {
00174 public boolean accept(File dir, String name)
00175 {
00176 return name.endsWith(".jar");
00177 }
00178 });
00179
00180 if (jarFiles == null)
00181 throw new IOException("Invalid path " + dir);
00182
00183
00184 for (int i = 0; i < jarFiles.length; i++)
00185 {
00186 File file = new File(dir, jarFiles[i]);
00187 JarFile jarFile = new JarFile(file);
00188
00189
00190
00191
00192 if (jarFile.getEntry(resourceName) != null)
00193 {
00194
00195 loadJarFile(jarFile.getName());
00196
00197
00198 classBytes = (byte[]) htJarContents.get(resourceName);
00199 }
00200 }
00201 return classBytes;
00202 }
00203
00204
00205
00206
00207 protected URL findResource(String name)
00208 {
00209
00210
00211 if (path.isDirectory())
00212 {
00213 File searchResource = new File(path, name);
00214 if (searchResource.exists())
00215 {
00216 try
00217 {
00218 return searchResource.toURL();
00219 }
00220 catch (MalformedURLException mfe)
00221 {
00222 }
00223 }
00224 }
00225 else if (path.isFile())
00226 {
00227
00228 try
00229 {
00230 new JarFile(path);
00231
00232 return new URL("jar:" + path.toURL() + "!/" + name);
00233 }
00234 catch (Exception e)
00235 {
00236
00237 return null;
00238 }
00239 }
00240
00241
00242 try
00243 {
00244
00245 String[] jarFiles = path.list(new FilenameFilter()
00246 {
00247 public boolean accept(File dir, String name)
00248 {
00249 return name.endsWith(".jar");
00250 }
00251 });
00252
00253 for (int i = 0; i < jarFiles.length; i++)
00254 {
00255 File file = new File(path, jarFiles[i]);
00256 JarFile jarFile = new JarFile(file);
00257
00258
00259 if (jarFile.getJarEntry(name) != null)
00260 {
00261
00262 return new URL("jar:" + file.toURL() + "!/" + name);
00263 }
00264 }
00265 }
00266 catch (Exception e)
00267 {
00268 e.printStackTrace();
00269 }
00270 return null;
00271 }
00272
00273
00274
00275
00276
00277
00278
00279
00280 private String convertClassNameToResourceName(String className)
00281 {
00282 String resourceName = className;
00283 resourceName = resourceName.replace('.', '/');
00284 resourceName = resourceName + ".class";
00285 return resourceName;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294 private void loadJarFile(String jarFileName) throws IOException
00295 {
00296 Hashtable htSizes = new Hashtable();
00297
00298
00299
00300
00301 ZipFile zf = new ZipFile(jarFileName);
00302 Enumeration e = zf.entries();
00303 while (e.hasMoreElements())
00304 {
00305 ZipEntry ze = (ZipEntry) e.nextElement();
00306
00307 htSizes.put(ze.getName(), new Integer((int) ze.getSize()));
00308 }
00309 zf.close();
00310
00311
00312 FileInputStream fis = new FileInputStream(jarFileName);
00313 BufferedInputStream bis = new BufferedInputStream(fis);
00314 ZipInputStream zis = new ZipInputStream(bis);
00315 ZipEntry ze = null;
00316 while ((ze = zis.getNextEntry()) != null)
00317 {
00318 if (ze.isDirectory())
00319 {
00320 continue;
00321 }
00322
00323 int size = (int) ze.getSize();
00324
00325 if (size == -1)
00326 {
00327
00328 size = ((Integer) htSizes.get(ze.getName())).intValue();
00329 }
00330
00331 byte[] b = new byte[size];
00332 int rb = 0;
00333 int chunk = 0;
00334 while ((size - rb) > 0)
00335 {
00336 chunk = zis.read(b, rb, size - rb);
00337 if (chunk == -1)
00338 {
00339 break;
00340 }
00341 rb += chunk;
00342 }
00343
00344
00345 htJarContents.put(ze.getName(), b);
00346 }
00347
00348 }
00349 }