/Users/lyon/j4p/src/classUtils/pack/util/AutoClassLoader.java

1    /* 
2     * AutoClassLoader.java 
3     * 
4     * Created on 15. august 2001, 16:39 
5     */ 
6     
7    package classUtils.pack.util; 
8     
9    import java.io.BufferedInputStream; 
10   import java.io.ByteArrayOutputStream; 
11   import java.io.File; 
12   import java.io.FilenameFilter; 
13   import java.io.IOException; 
14   import java.util.StringTokenizer; 
15   import java.util.jar.JarFile; 
16   import java.util.jar.JarEntry; 
17    
18   /** 
19    * A ClassLoader implementation which looks up the JARs in classpath and loads them 
20    * individually, without the need of specifying one by one. The JARs are loaded 
21    * in the same order they appear in the directory listing. 
22    * 
23    * @author  Cristiano Sadun 
24    * @version 1.0.1 
25    */ 
26   public class AutoClassLoader extends java.lang.ClassLoader { 
27    
28       /** 
29        * The classpath resulting by looking up directories for JARs. 
30        * Set up by expandClasspath() 
31        */ 
32       private static String cpath = null; 
33        
34       /** 
35        * The path separator. Set up at construction. 
36        */ 
37       private static String pathSep = null; 
38        
39    
40       /** Creates new AutoClassLoader */ 
41       public AutoClassLoader() { 
42           super(); 
43           if (pathSep == null) { 
44               pathSep = System.getProperty("path.separator"); 
45           } 
46       } 
47    
48       /** Creates new AutoClassLoader */ 
49       public AutoClassLoader(ClassLoader parent) { 
50           super(parent); 
51           if (pathSep == null) { 
52               pathSep = System.getProperty("path.separator"); 
53           } 
54       } 
55    
56       private String expandClassPath() { 
57           String cp = System.getProperty("java.class.path"); 
58           StringTokenizer st = new StringTokenizer(cp,pathSep); 
59           StringBuffer sb = new StringBuffer(); 
60           boolean finished=! st.hasMoreTokens(); 
61           while(! finished) { 
62               String cpElem = st.nextToken(); 
63               sb.append(cp+pathSep); 
64               File f = new File(cpElem); 
65               if (f.isDirectory() && f.exists()) 
66                   sb.append(getJarsInDirectory(f, pathSep)); 
67               else sb.append(cpElem); 
68               if (st.hasMoreTokens()) sb.append(pathSep); 
69               else finished=true; 
70           } 
71           return sb.toString(); 
72       } 
73    
74       private String getJarsInDirectory(File f, String separator) { 
75        String [] files = f.list(new FilenameFilter() { 
76            public boolean accept(File dir, String name) { 
77                return name.endsWith(".jar"); 
78            } 
79        }); 
80        StringBuffer sb=new StringBuffer(); 
81        for(int i=0;i<files.length;i++) { 
82            sb.append(f.getAbsolutePath()+File.separator+files[i]); 
83            if (i<files.length) sb.append(separator); 
84        } 
85        return sb.toString(); 
86       } 
87    
88       /** 
89        * Finds a class in the expanded class path 
90        * @exception ClassNotFoundException if the class cannot be found 
91        */ 
92       protected Class findClass(String name) throws ClassNotFoundException { 
93           if (cpath==null) cpath=expandClassPath(); 
94    
95           // Look in the expanded classpath, using the standard classloader 
96           StringTokenizer st = new StringTokenizer(cpath,pathSep); 
97           while(st.hasMoreTokens()) { 
98               String entry = st.nextToken(); 
99               if (!entry.endsWith(".jar")) continue; 
100   
101              Class cls; 
102              if ((cls=lookInJar(name, entry))!=null) return cls; 
103          } 
104          throw new ClassNotFoundException(name); 
105      } 
106   
107      private Class lookInJar(String clsName, String jarFileName) throws ClassNotFoundException { 
108              try { 
109                  JarFile jarFile = new JarFile(jarFileName); 
110                  String entryName=clsName.replace('.','/')+".class"; 
111                  JarEntry entry = jarFile.getJarEntry(entryName); 
112                  if(entry==null) return null; 
113   
114                  System.out.println(clsName+" found in "+jarFileName); 
115   
116                  BufferedInputStream is = new BufferedInputStream(jarFile.getInputStream(entry)); 
117                  ByteArrayOutputStream os = new ByteArrayOutputStream(); 
118                  for(long i=0;i<entry.getSize();i++) 
119                     os.write(is.read()); 
120   
121              byte [] b = os.toByteArray(); 
122   
123                  return defineClass(clsName, b, 0, b.length); 
124              } catch(IOException e) { 
125                  throw new ClassNotFoundException("Can't load "+clsName+" from "+jarFileName, e); 
126              } 
127      } 
128   
129     public static void main(String args[]) throws Exception { 
130   
131        System.setProperty("java.class.path","c:\\xtractor\\dev\\core\\lib;c:\\xtractor\\dev\\core\\lib\\3rd"); 
132        AutoClassLoader cl = new AutoClassLoader(ClassLoader.getSystemClassLoader()); 
133        Class cls = cl.loadClass("com.metamata.util.ZipPath"); 
134     } 
135   
136   
137  } 
138