KickJava   Java API By Example, From Geeks To Geeks.

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


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.config.types.FileSetType;
33 import com.caucho.config.types.PathPatternType;
34 import com.caucho.make.DependencyContainer;
35 import com.caucho.server.util.CauchoSystem;
36 import com.caucho.util.CharBuffer;
37 import com.caucho.vfs.Depend;
38 import com.caucho.vfs.Dependency;
39 import com.caucho.vfs.JarPath;
40 import com.caucho.vfs.Path;
41
42 import javax.annotation.PostConstruct;
43 import java.net.URL JavaDoc;
44 import java.util.ArrayList JavaDoc;
45 import java.util.Vector JavaDoc;
46 import java.util.logging.Level JavaDoc;
47 import java.util.logging.Logger JavaDoc;
48
49 /**
50  * Class loader which checks for changes in class files and automatically
51  * picks up new jars.
52  */

53 public class LibraryLoader extends Loader implements Dependency {
54   private static final Logger JavaDoc log
55     = Logger.getLogger(DirectoryLoader.class.getName());
56   
57   // Configured path.
58
private Path _path;
59   
60   private FileSetType _fileSet;
61
62   // When the directory was last modified
63
private long _lastModified;
64
65   private String JavaDoc []_fileNames;
66
67   // list of the matching paths
68
private ArrayList JavaDoc<Path> _pathList = new ArrayList JavaDoc<Path>();
69
70   // list of the matching paths
71
private ArrayList JavaDoc<Path> _newPathList = new ArrayList JavaDoc<Path>();
72   
73   // list of the jars in the directory
74
private ArrayList JavaDoc<JarEntry> _jarList;
75   
76   // list of dependencies
77
private DependencyContainer _dependencyList = new DependencyContainer();
78
79   /**
80    * Creates a new directory loader.
81    */

82   public LibraryLoader()
83   {
84   }
85
86   /**
87    * Creates a new directory loader.
88    */

89   public LibraryLoader(Path path)
90   {
91     _path = path;
92
93     try {
94       init();
95     } catch (Exception JavaDoc e) {
96       throw new RuntimeException JavaDoc(e);
97     }
98   }
99
100   /**
101    * The library loader's path.
102    */

103   public void setPath(Path path)
104   {
105     _path = path;
106   }
107
108   /**
109    * The library loader's path.
110    */

111   public Path getPath()
112   {
113     return _path;
114   }
115
116   /**
117    * Sets a file set.
118    */

119   public void setFileSet(FileSetType fileSet)
120   {
121     _fileSet = fileSet;
122   }
123
124   /**
125    * Create a new class loader
126    *
127    * @param parent parent class loader
128    * @param dir directories which can handle dynamic jar addition
129    */

130   public static DynamicClassLoader create(ClassLoader JavaDoc parent, Path path)
131   {
132     DynamicClassLoader loader = new DynamicClassLoader(parent);
133
134     LibraryLoader dirLoader = new LibraryLoader(path);
135
136     loader.addLoader(dirLoader);
137
138     loader.init();
139     
140     return loader;
141   }
142
143   /**
144    * Initialize
145    */

146   @PostConstruct
147   public void init()
148     throws ConfigException
149   {
150     try {
151       if (_fileSet != null) {
152       }
153       else if (_path.getPath().endsWith(".jar") ||
154            _path.getPath().endsWith(".zip")) {
155     _fileSet = new FileSetType();
156     _fileSet.setDir(_path.getParent());
157     _fileSet.addInclude(new PathPatternType(_path.getTail()));
158       }
159       else {
160     _fileSet = new FileSetType();
161     _fileSet.setDir(_path);
162     _fileSet.addInclude(new PathPatternType("*.jar"));
163     _fileSet.addInclude(new PathPatternType("*.zip"));
164       }
165
166       _jarList = new ArrayList JavaDoc<JarEntry>();
167       _dependencyList = new DependencyContainer();
168
169       fillJars();
170     } catch (ConfigException e) {
171       throw e;
172     } catch (Exception JavaDoc e) {
173       throw new ConfigException(e);
174     }
175   }
176
177   /**
178    * Sets the owning class loader.
179    */

180   public void setLoader(DynamicClassLoader loader)
181   {
182     super.setLoader(loader);
183
184     for (int i = 0; i < _jarList.size(); i++)
185       loader.addURL(_jarList.get(i).getJarPath());
186   }
187
188   /**
189    * Validates the loader.
190    */

191   public void validate()
192     throws ConfigException
193   {
194     for (int i = 0; i < _jarList.size(); i++) {
195       _jarList.get(i).validate();
196     }
197   }
198   
199   /**
200    * True if any of the loaded classes have been modified. If true, the
201    * caller should drop the classpath and create a new one.
202    */

203   public boolean isModified()
204   {
205     _newPathList.clear();
206
207     _fileSet.getPaths(_newPathList);
208
209     return ! _newPathList.equals(_pathList);
210   }
211
212   /**
213    * Find all the jars in this directory and add them to jarList.
214    */

215   private void fillJars()
216   {
217     _pathList.clear();
218     _jarList.clear();
219
220     _fileSet.getPaths(_pathList);
221
222     for (int i = 0; i < _pathList.size(); i++) {
223       Path jar = _pathList.get(i);
224
225       addJar(jar);
226     }
227   }
228
229   private void addJar(Path jar)
230   {
231     JarPath jarPath = JarPath.create(jar);
232     _jarList.add(new JarEntry(jarPath));
233
234     _dependencyList.add(new Depend(jarPath));
235
236     if (getLoader() != null)
237       getLoader().addURL(jarPath);
238   }
239
240   /**
241    * Fill data for the class path. fillClassPath() will add all
242    * .jar and .zip files in the directory list.
243    */

244   protected String JavaDoc getClassPath(String JavaDoc head)
245   {
246     CharBuffer cb = new CharBuffer();
247
248     cb.append(head);
249
250     for (int i = 0; i < _jarList.size(); i++) {
251       JarEntry jarEntry = _jarList.get(i);
252       JarPath jar = jarEntry.getJarPath();
253
254       if (cb.length() > 0)
255         cb.append(CauchoSystem.getPathSeparatorChar());
256       cb.append(jar.getContainer().getNativePath());
257     }
258
259     return cb.close();
260   }
261
262   /**
263    * Returns the class entry.
264    *
265    * @param name name of the class
266    */

267   protected ClassEntry getClassEntry(String JavaDoc name)
268     throws ClassNotFoundException JavaDoc
269   {
270     String JavaDoc pathName = name.replace('.', '/');
271     
272     String JavaDoc pkg = "";
273     int p = pathName.lastIndexOf('/');
274     if (p > 0)
275       pkg = pathName.substring(0, p + 1);
276          
277     pathName = pathName + ".class";
278
279     Path classPath = null;
280     
281     // Find the path corresponding to the class
282
for (int i = 0; i < _jarList.size(); i++) {
283       JarEntry jarEntry = _jarList.get(i);
284       Path path = jarEntry.getJarPath();
285
286       Path filePath = path.lookup(pathName);
287       
288       if (filePath.canRead() && filePath.getLength() > 0) {
289         ClassEntry entry = new ClassEntry(getLoader(), name, filePath,
290                                           filePath,
291                       jarEntry.getCodeSource(pathName));
292
293         ClassPackage classPackage = jarEntry.getPackage(pkg);
294
295         entry.setClassPackage(classPackage);
296
297         return entry;
298       }
299     }
300
301     return null;
302   }
303   
304   /**
305    * Adds resources to the enumeration.
306    */

307   public void getResources(Vector JavaDoc<URL JavaDoc> vector, String JavaDoc name)
308   {
309     for (int i = 0; i < _jarList.size(); i++) {
310       JarEntry jarEntry = _jarList.get(i);
311       Path path = jarEntry.getJarPath();
312
313       path = path.lookup(name);
314
315       if (path.canRead() || path.isDirectory()) {
316     try {
317       vector.add(new URL JavaDoc(path.getURL()));
318     } catch (Exception JavaDoc e) {
319       log.log(Level.WARNING, e.toString(), e);
320     }
321       }
322     }
323   }
324
325   /**
326    * Find a given path somewhere in the classpath
327    *
328    * @param pathName the relative resourceName
329    *
330    * @return the matching path or null
331    */

332   public Path getPath(String JavaDoc pathName)
333   {
334     for (int i = 0; i < _jarList.size(); i++) {
335       JarEntry jarEntry = _jarList.get(i);
336       Path path = jarEntry.getJarPath();
337
338       Path filePath = path.lookup(pathName);
339
340       if (filePath.exists())
341     return filePath;
342     }
343
344     return null;
345   }
346
347   public Path getCodePath()
348   {
349     return _fileSet.getDir();
350   }
351
352   /**
353    * Destroys the loader, closing the jars.
354    */

355   protected void destroy()
356   {
357     clearJars();
358   }
359
360   /**
361    * Closes the jars.
362    */

363   private void clearJars()
364   {
365     ArrayList JavaDoc<JarEntry> jars = new ArrayList JavaDoc<JarEntry>(_jarList);
366     _jarList.clear();
367     
368     for (int i = 0; i < jars.size(); i++) {
369       JarEntry jarEntry = jars.get(i);
370
371       JarPath jarPath = jarEntry.getJarPath();
372
373       jarPath.closeJar();
374     }
375   }
376
377   public String JavaDoc toString()
378   {
379     return "LibraryLoader[" + _fileSet + "]";
380   }
381 }
382
Popular Tags