KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > loader > DirectoryLoader


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.loader;
30
31 import com.caucho.config.ConfigException;
32 import com.caucho.make.DependencyContainer;
33 import com.caucho.util.CharBuffer;
34 import com.caucho.vfs.Dependency;
35 import com.caucho.vfs.JarPath;
36 import com.caucho.vfs.Path;
37
38 import java.io.IOException JavaDoc;
39 import java.net.URL JavaDoc;
40 import java.util.ArrayList JavaDoc;
41 import java.util.Vector JavaDoc;
42 import java.util.logging.Level JavaDoc;
43 import java.util.logging.Logger JavaDoc;
44
45 /**
46  * Class loader which checks for changes in class files and automatically
47  * picks up new jars.
48  */

49 public class DirectoryLoader extends Loader implements Dependency
50 {
51   private static final Logger JavaDoc log
52     = Logger.getLogger(DirectoryLoader.class.getName());
53   
54   // Directory which may have jars dynamically added
55
private Path _dir;
56
57   // When the directory was last modified
58
private long _lastModified;
59
60   private String JavaDoc []_fileNames;
61
62   // list of the jars in the directory
63
private ArrayList JavaDoc<JarEntry> _jarList;
64   
65   // list of dependencies
66
private DependencyContainer _dependencyList = new DependencyContainer();
67
68   /**
69    * Creates a new directory loader.
70    */

71   public DirectoryLoader()
72   {
73   }
74
75   /**
76    * Creates a new directory loader.
77    */

78   public DirectoryLoader(Path dir)
79   {
80     _dir = dir;
81
82     init();
83   }
84
85   /**
86    * The directory loader's path.
87    */

88   public void setPath(Path path)
89   {
90     _dir = path;
91   }
92
93   /**
94    * The directory loader's path.
95    */

96   public Path getPath()
97   {
98     return _dir;
99   }
100
101   /**
102    * Create a new class loader
103    *
104    * @param parent parent class loader
105    * @param dir directories which can handle dynamic jar addition
106    */

107   public static DynamicClassLoader create(ClassLoader JavaDoc parent, Path dir)
108   {
109     DynamicClassLoader loader = new DynamicClassLoader(parent);
110
111     DirectoryLoader dirLoader = new DirectoryLoader(dir);
112
113     loader.addLoader(dirLoader);
114
115     loader.init();
116     
117     return loader;
118   }
119
120   /**
121    * Initialize
122    */

123   public void init()
124   {
125     _lastModified = _dir.getLastModified();
126     
127     try {
128       _fileNames = _dir.list();
129     } catch (IOException JavaDoc e) {
130     }
131
132     _jarList = new ArrayList JavaDoc<JarEntry>();
133     _dependencyList = new DependencyContainer();
134
135     fillJars();
136   }
137
138   /**
139    * Sets the owning class loader.
140    */

141   public void setLoader(DynamicClassLoader loader)
142   {
143     super.setLoader(loader);
144
145     for (int i = 0; i < _jarList.size(); i++)
146       loader.addURL(_jarList.get(i).getJarPath());
147   }
148
149   /**
150    * Validates the loader.
151    */

152   public void validate()
153     throws ConfigException
154   {
155     for (int i = 0; i < _jarList.size(); i++) {
156       _jarList.get(i).validate();
157     }
158   }
159   
160   /**
161    * True if any of the loaded classes have been modified. If true, the
162    * caller should drop the classpath and create a new one.
163    */

164   public boolean isModified()
165   {
166     if (_lastModified < _dir.getLastModified())
167       return true;
168
169     String JavaDoc []list = null;
170
171     try {
172       list = _dir.list();
173     } catch (IOException JavaDoc e) {
174     }
175
176     if (_fileNames.length != list.length ||
177         ((_fileNames == null) != (list == null)))
178       return true;
179
180     if (_fileNames != null) {
181       for (int i = 0; i < _fileNames.length; i++)
182         if (! _fileNames[i].equals(list[i]))
183           return true;
184     }
185
186     return _dependencyList.isModified();
187   }
188
189   /**
190    * Find all the jars in this directory and add them to jarList.
191    */

192   private void fillJars()
193   {
194     _jarList.clear();
195
196     String JavaDoc []list = null;
197
198     try {
199       list = _dir.list();
200     } catch (IOException JavaDoc e) {
201     }
202
203     for (int j = 0; list != null && j < list.length; j++) {
204       if (list[j].endsWith(".jar") || list[j].endsWith(".zip")) {
205         Path jar = _dir.lookup(list[j]);
206
207         addJar(jar);
208       }
209     }
210   }
211
212   private void addJar(Path jar)
213   {
214     JarPath jarPath = JarPath.create(jar);
215     JarEntry jarEntry = new JarEntry(jarPath);
216
217     if (_jarList.contains(jarEntry))
218       return;
219     
220     _jarList.add(jarEntry);
221
222     _dependencyList.add(jarPath.getDepend());
223
224     if (getLoader() != null)
225       getLoader().addURL(jarPath);
226   }
227
228   /**
229    * Fill data for the class path. fillClassPath() will add all
230    * .jar and .zip files in the directory list.
231    */

232   protected String JavaDoc getClassPath(String JavaDoc head)
233   {
234     CharBuffer cb = new CharBuffer();
235
236     cb.append(head);
237
238     for (int i = 0; i < _jarList.size(); i++) {
239       JarEntry jarEntry = _jarList.get(i);
240       JarPath jar = jarEntry.getJarPath();
241
242       if (cb.length() > 0)
243         cb.append(Path.getPathSeparatorChar());
244       cb.append(jar.getContainer().getNativePath());
245     }
246
247     return cb.close();
248   }
249
250   /**
251    * Returns the class entry.
252    *
253    * @param name name of the class
254    */

255   protected ClassEntry getClassEntry(String JavaDoc name)
256     throws ClassNotFoundException JavaDoc
257   {
258     String JavaDoc pathName = name.replace('.', '/');
259     
260     String JavaDoc pkg = "";
261     int p = pathName.lastIndexOf('/');
262     if (p > 0)
263       pkg = pathName.substring(0, p + 1);
264          
265     pathName = pathName + ".class";
266
267     Path classPath = null;
268     
269     // Find the path corresponding to the class
270
for (int i = 0; i < _jarList.size(); i++) {
271       JarEntry jarEntry = _jarList.get(i);
272       Path path = jarEntry.getJarPath();
273
274       Path filePath = path.lookup(pathName);
275       
276       if (filePath.canRead() && filePath.getLength() > 0) {
277         ClassEntry entry = new ClassEntry(getLoader(), name, filePath,
278                                           filePath,
279                       jarEntry.getCodeSource(pathName));
280
281         ClassPackage classPackage = jarEntry.getPackage(pkg);
282
283         entry.setClassPackage(classPackage);
284
285         return entry;
286       }
287     }
288
289     return null;
290   }
291   
292   /**
293    * Adds resources to the enumeration.
294    */

295   public void getResources(Vector JavaDoc<URL JavaDoc> vector, String JavaDoc name)
296   {
297     for (int i = 0; i < _jarList.size(); i++) {
298       JarEntry jarEntry = _jarList.get(i);
299       Path path = jarEntry.getJarPath();
300
301       path = path.lookup(name);
302
303       if (path.canRead()) {
304     try {
305       vector.add(new URL JavaDoc(path.getURL()));
306     } catch (Exception JavaDoc e) {
307       log.log(Level.WARNING, e.toString(), e);
308     }
309       }
310     }
311   }
312
313   /**
314    * Find a given path somewhere in the classpath
315    *
316    * @param pathName the relative resourceName
317    *
318    * @return the matching path or null
319    */

320   public Path getPath(String JavaDoc pathName)
321   {
322     for (int i = 0; i < _jarList.size(); i++) {
323       JarEntry jarEntry = _jarList.get(i);
324       Path path = jarEntry.getJarPath();
325
326       Path filePath = path.lookup(pathName);
327
328       if (filePath.exists())
329     return filePath;
330     }
331
332     return null;
333   }
334
335   public Path getCodePath()
336   {
337     return _dir;
338   }
339
340   public boolean equals(Object JavaDoc o)
341   {
342     if (o == null || getClass() != o.getClass())
343       return false;
344
345     DirectoryLoader loader = (DirectoryLoader) o;
346
347     return _dir.equals(loader._dir);
348   }
349
350   public String JavaDoc toString()
351   {
352     return "DirectoryLoader[" + _dir + "]";
353   }
354 }
355
Popular Tags