--- /dev/null
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
+package org.ibex.jinetd;
+import org.ibex.io.*;
+import org.ibex.util.*;
+import java.io.*;
+import java.util.*;
+import java.text.*;
+import java.net.*;
+import java.util.zip.*;
+
+public class TreeClassLoader extends URLClassLoader {
+
+ private final File root;
+ private final File lib;
+ private Hashtable cache = new Hashtable();
+
+ public TreeClassLoader(File root, ClassLoader parent) {
+ super(new URL[] { }, parent);
+ this.root = root;
+ this.lib = new File(root.getAbsolutePath() + File.separatorChar + "lib");
+ }
+
+ // Classloading //////////////////////////////////////////////////////////////////////////////
+
+ public URL[] getURLs() {
+ try {
+ Vec v = new Vec();
+ if (getParent() != null && getParent() instanceof URLClassLoader) {
+ URL[] parentUrls = ((URLClassLoader)getParent()).getURLs();
+ for(int i=0; i<parentUrls.length; i++) v.addElement(parentUrls[i]);
+ }
+ String vmClasspath =
+ System.getProperty("java.class.path") +
+ File.pathSeparatorChar +
+ System.getProperty("sun.boot.class.path");
+ StringTokenizer st = new StringTokenizer(vmClasspath, File.pathSeparatorChar+"");
+ while(st.hasMoreTokens()) v.addElement(new URL("file:" + st.nextToken()));
+ v.addElement(new URL("file:" + root.getAbsolutePath()));
+ v.addElement(new URL("file:" + root.getAbsolutePath() + File.separatorChar + "classes"));
+ for(Enumeration e = enumerateJarFiles(); e.hasMoreElements(); )
+ v.addElement(new URL("file:" + ((File)e.nextElement()).getAbsolutePath()));
+ return (URL[])v.copyInto(new URL[v.size()]);
+ } catch (MalformedURLException e) {
+ Log.error(this, e);
+ return null;
+ }
+ }
+
+ private synchronized Class defineClass(String name) throws ClassNotFoundException {
+ InputStream is = null;
+ try {
+ is = getClassInputStream(name);
+ if (is == null) return null;
+ byte[] b = InputStreamToByteArray.convert(is);
+ Class ret = defineClass(b, 0, b.length);
+ cache.put(name, ret);
+ return ret;
+ } catch (Exception e) {
+ Log.error(this, e);
+ throw new ClassNotFoundException();
+ } finally {
+ if (is != null) try { is.close(); } catch (Exception e) { Log.error(this, e); }
+ }
+ }
+
+ public synchronized Class findClass(String name) throws ClassNotFoundException {
+ Class c = (Class)cache.get(name);
+ if (c==null) c = defineClass(name);
+ if (c==null) throw new ClassNotFoundException(name);
+ return c;
+ }
+
+ // Filesystem Methods //////////////////////////////////////////////////////////////////////////////
+
+ private static final FilenameFilter jarFilter =
+ new FilenameFilter() { public boolean accept(File f, String s) {return s.endsWith(".jar");}};
+ public Enumeration enumerateJarFiles() {
+ Enumeration rootJars =
+ new Misc.ArrayEnumeration(root.list(jarFilter)) {
+ public Object nextElement() { return new File(root.getAbsolutePath()+File.separatorChar+super.nextElement()); } };
+ Enumeration libJars =
+ new Misc.ArrayEnumeration(lib.list(jarFilter)) {
+ public Object nextElement() { return new File(lib.getAbsolutePath()+File.separatorChar+super.nextElement()); } };
+ return new Misc.JoinEnumeration(rootJars, libJars);
+ }
+
+ public InputStream getResourceAsStream(String name) {
+ InputStream ret = getInputStream(name);
+ if (ret == null) ret = getParent().getResourceAsStream(name);
+ return ret;
+ }
+
+ public InputStream getClassInputStream(String classname) { return getInputStream(classname.replace('.', '/')+".class"); }
+ public InputStream getInputStream(String name) {
+ try {
+ File f = new File(root.getAbsolutePath() + File.separatorChar + name);
+ if (f.exists()) return new FileInputStream(f);
+ } catch (IOException e) { /* DELIBERATE */ }
+ try {
+ File f = new File("classes" + File.separatorChar + root.getAbsolutePath() + File.separatorChar + name);
+ if (f.exists()) return new FileInputStream(f);
+ } catch (IOException e) { /* DELIBERATE */ }
+ for(Enumeration e = enumerateJarFiles(); e.hasMoreElements();) try {
+ ZipFile zf = new ZipFile((File)e.nextElement());
+ ZipEntry ze = zf.getEntry(name);
+ if (ze != null) return zf.getInputStream(ze);
+ zf.close();
+ } catch (Exception ex) { Log.warn(this, ex); }
+ return null;
+ }
+
+}