KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > it > businesslogic > ireport > ReportClassLoader


1 /*
2  * Copyright (C) 2005 - 2006 JasperSoft Corporation. All rights reserved.
3  * http://www.jaspersoft.com.
4  *
5  * Unless you have purchased a commercial license agreement from JasperSoft,
6  * the following license terms apply:
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as published by
10  * the Free Software Foundation.
11  *
12  * This program is distributed WITHOUT ANY WARRANTY; and without the
13  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see http://www.gnu.org/licenses/gpl.txt
18  * or write to:
19  *
20  * Free Software Foundation, Inc.,
21  * 59 Temple Place - Suite 330,
22  * Boston, MA USA 02111-1307
23  *
24  *
25  *
26  *
27  * ReportClassLoader.java
28  *
29  * Created on 24 maggio 2004, 12.56
30  *
31  */

32
33 package it.businesslogic.ireport;
34
35 import java.io.ByteArrayOutputStream JavaDoc;
36 import java.io.File JavaDoc;
37 import java.io.FileInputStream JavaDoc;
38 import java.io.IOException JavaDoc;
39 import java.io.InputStream JavaDoc;
40 import java.net.URL JavaDoc;
41 import java.net.URLClassLoader JavaDoc;
42 import java.util.ArrayList JavaDoc;
43 import java.util.HashMap JavaDoc;
44 import java.util.StringTokenizer JavaDoc;
45 import java.util.zip.ZipEntry JavaDoc;
46 import java.util.zip.ZipFile JavaDoc;
47 import java.util.*;
48
49 /**
50  * This special class loader is used when running a report.
51  * The main feature is that this classloader reload Scriptlet class every
52  * time the class is needed.
53  * This class is based on JUnit test case class loader.
54  * @author Administrator
55  */

56 public class ReportClassLoader extends java.lang.ClassLoader JavaDoc {
57         
58     /** scanned class path */
59     private ArrayList JavaDoc fPathItems;
60     
61     /** scanned class path */
62     private ArrayList JavaDoc fPathChachedItems;
63     private HashMap JavaDoc cachedClasses;
64     
65     /** default excluded paths */
66
67     /**
68      * Constructs a ReloadableTestClassLoader. It tokenizes the value of
69      * <code>reportPath</code> and adds it and any sub-paths to a list.
70      * Paths are searched for tests. All other classes are loaded
71      * by parent loaders, to which this classloader always delegates.
72      *
73      * This ClassLoader never looks into or knows about the system classpath.
74      * It should always refer to a path of repositories (jars or dirs)
75      * <em>not</em> on the system classpath (as retrieved via
76      * <code>reportPath</code>).
77      *
78      * @param classPath to scan and use for finding and reloading classes
79      */

80     public ReportClassLoader() {
81         super( ReportClassLoader.class.getClassLoader() );
82         setup();
83     }
84     
85      public ReportClassLoader(ClassLoader JavaDoc parent) {
86          
87         super(parent);
88         setup();
89      }
90      
91      private void setup()
92      {
93         fPathItems = new ArrayList JavaDoc();
94         fPathChachedItems = new ArrayList JavaDoc();
95         cachedClasses = new HashMap JavaDoc();
96         rescanLibDirectory();
97      }
98     
99     /**
100      * Add to search paths list as no relodable jar/zip all new .jar,.zip not already in classpath
101      */

102     public void rescanLibDirectory()
103     {
104         try {
105             rescanAdditionalClasspath();
106         } catch (Exception JavaDoc ex) {}
107         
108         if (it.businesslogic.ireport.gui.MainFrame.getMainInstance() == null) return;
109         // Looking for jars or zip in lib directory not in classpath...
110
String JavaDoc irHome = it.businesslogic.ireport.gui.MainFrame.getMainInstance().IREPORT_HOME_DIR;
111     if (irHome == null) irHome = System.getProperty("ireport.home",".");
112     File JavaDoc lib_dir = new File JavaDoc(irHome,"lib");
113         String JavaDoc classpath = it.businesslogic.ireport.util.Misc.nvl(System.getProperty("java.class.path"),"");
114         if (!lib_dir.exists())
115         {
116             System.out.println("Cannot find lib in iReport home directory ("+it.businesslogic.ireport.gui.MainFrame.getMainInstance().IREPORT_HOME_DIR+")");
117             return;
118         }
119
120         //System.out.println("Rescan lib...");
121
File JavaDoc[] new_libs = lib_dir.listFiles();
122
123         for (int i=0; i< new_libs.length; ++i)
124         {
125             if (!new_libs[i].getName().toLowerCase().endsWith("jar") &&
126                 !new_libs[i].getName().toLowerCase().endsWith("zip")) continue;
127             
128             if (classpath.indexOf( new_libs[i].getName()) < 0)
129             {
130                 try {
131                     if (!fPathChachedItems.contains(new_libs[i].getCanonicalPath()))
132                     {
133                         //if ( new File(new_libs[i].getAbsolutePath()).exists())
134
//{
135
//System.out.println("Added lib " + new_libs[i].getCanonicalPath() + " to ireport class path\n");
136
fPathChachedItems.add(new_libs[i].getCanonicalPath());
137                         //}
138
}
139                 } catch (Exception JavaDoc ex)
140                 {
141                     System.out.println("Invalid path: " + new_libs[i]);
142                 }
143             }
144         }
145     }
146     
147     public java.util.List JavaDoc getCachedItems()
148     {
149         return fPathChachedItems;
150     }
151     
152     public void clearCache()
153     {
154         cachedClasses.clear();
155         //System.out.println("Cached classes " + cachedClasses);
156
}
157     
158     /**
159      * Add to search paths list as no relodable jar/zip all new .jar,.zip not already in classpath
160      */

161     public void rescanAdditionalClasspath()
162     {
163         if (it.businesslogic.ireport.gui.MainFrame.getMainInstance() == null) return;
164         // Looking for jars or zip in lib directory not in classpath...
165
Vector cp = it.businesslogic.ireport.gui.MainFrame.getMainInstance().getClasspath();
166         for (int i=0; i<cp.size(); ++i)
167         {
168             File JavaDoc f = new File JavaDoc( cp.elementAt(i) + "" );
169             if (!f.exists()) continue;
170             try {
171                 if (!fPathChachedItems.contains(f.getCanonicalPath()))
172                 {
173                       //System.out.println("Added dynamically " + f.getCanonicalPath() + " to ireport class path");
174
fPathChachedItems.add(f.getCanonicalPath());
175                 }
176             } catch (Exception JavaDoc ex)
177             {
178                 System.out.println("Invalid path: " + f);
179             }
180                    
181             
182         }
183     }
184         
185     /**
186      * Add a dir or a file (i.e. a jar or a zip) to the search path
187      */

188     public void addNoRelodablePath(String JavaDoc path)
189     {
190         if (!fPathChachedItems.contains(path))
191         {
192           fPathChachedItems.add(path);
193         }
194     }
195     
196     public void setRelodablePaths(String JavaDoc classPath)
197     {
198        scanPath(classPath);
199     }
200
201     private void scanPath(String JavaDoc classPath) {
202         String JavaDoc separator = System.getProperty("path.separator");
203         fPathItems = new ArrayList JavaDoc(31);
204         StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(classPath, separator);
205         while (st.hasMoreTokens()) {
206             String JavaDoc pp = st.nextToken();
207             //System.out.println("add " + pp);
208
fPathItems.add(pp);
209         }
210     }
211
212     public URL JavaDoc getResource(String JavaDoc name) {
213                 // We have to try to solve the name...
214
return this.findResource(name);
215         /*
216         for (int i = 0; i < fPathChachedItems.size(); i++) {
217             String path = (String) fPathChachedItems.get(i);
218             
219             if (isJar(path))
220             {
221                 InputStream is = getInputStreamFromJar(path, name);
222                 if (is != null)
223                 {
224                     try {
225                         is.close();
226                         File f = new File(path);
227                         System.out.println("jar:" + f.toURL() + "!" + name);
228                         return new URL("jar:" + f.toURL() + "!" + name);
229                         //return new URL("jar:file:/" + path + "!" + name);
230                     } catch (Exception ex)
231                     {}
232                 }
233             }
234             else
235             {
236                 File f = new File(path, name);
237                 if (f.exists())
238                 {
239                     try {
240                         return f.toURL();
241                         //return new URL("file:/" + f);
242                     } catch (Exception ex)
243                     {}
244                 }
245             }
246         }
247         
248         // Else try to load from reloadable paths...
249         for (int i = 0; i < fPathItems.size(); i++) {
250             
251             String path = (String) fPathItems.get(i);
252             
253             if (isJar(path))
254             {
255                 InputStream is = getInputStreamFromJar(path, name);
256                 if (is != null)
257                 {
258                     try {
259                         is.close();
260                         File f = new File(path);
261                         System.out.println("jar:" + f.toURL() + "!" + name);
262                         return new URL("jar:" + f.toURL() + "!" + name);
263                     } catch (Exception ex)
264                     {}
265                 }
266             }
267             else
268             {
269                 File f = new File(path, name);
270                 if (f.exists())
271                 {
272                     try {
273                         return f.toURL();
274                         //return new URL("file:/" + f);
275                     } catch (Exception ex)
276                     {}
277                 }
278             }
279         }
280         
281         return ClassLoader.getSystemResource(name);
282          **/

283     }
284
285     public InputStream JavaDoc getResourceAsStream(String JavaDoc name) {
286         
287         // We have to try to solve the name...
288
for (int i = 0; i < fPathChachedItems.size(); i++) {
289             String JavaDoc path = (String JavaDoc) fPathChachedItems.get(i);
290             
291             if (isJar(path))
292             {
293                 InputStream JavaDoc is = getInputStreamFromJar(path, name);
294                 if (is != null) return is;
295             }
296             else
297             {
298                 File JavaDoc f = new File JavaDoc(path, name);
299                 if (f.exists())
300                 {
301                      try {
302                         return new FileInputStream JavaDoc( f );
303                     } catch (Exception JavaDoc ex)
304                     {}
305                 }
306             }
307         }
308         
309         // Else try to load from reloadable paths...
310
for (int i = 0; i < fPathItems.size(); i++) {
311             
312             String JavaDoc path = (String JavaDoc) fPathItems.get(i);
313             
314             if (isJar(path))
315             {
316                 InputStream JavaDoc is = getInputStreamFromJar(path, name);
317                 if (is != null) return is;
318             }
319             else
320             {
321                 File JavaDoc f = new File JavaDoc(path, name);
322                 if (f.exists())
323                 {
324                      try {
325                         return new FileInputStream JavaDoc( f );
326                     } catch (Exception JavaDoc ex)
327                     {}
328                 }
329             }
330         }
331         
332         return ClassLoader.getSystemResourceAsStream(name);
333     }
334     
335        private InputStream JavaDoc getInputStreamFromJar(String JavaDoc archive_path, String JavaDoc fileName) {
336         ZipFile JavaDoc zipFile = null;
337         InputStream JavaDoc stream = null;
338         File JavaDoc archive = new File JavaDoc(archive_path);
339         if (!archive.exists())
340         {
341             //System.out.println("Il jar non esiste!");
342
return null;
343         }
344         try {
345             zipFile = new ZipFile JavaDoc(archive);
346         } catch (IOException JavaDoc io) {
347             //io.printStackTrace();
348
return null;
349         }
350         
351         //System.out.println("Ricerca entry" + fileName );
352
ZipEntry JavaDoc entry = zipFile.getEntry(fileName);
353         if (entry == null)
354         {
355             //System.out.println("Entry null!");
356
return null;
357         }
358         try {
359             return zipFile.getInputStream(entry);
360         } catch (IOException JavaDoc e) {
361         } finally {
362         }
363         
364         return null;
365     }
366     
367
368     public synchronized Class JavaDoc findClass(String JavaDoc name) throws ClassNotFoundException JavaDoc {
369
370         Class JavaDoc c = null;
371
372         if (cachedClasses.containsKey( name ))
373         {
374             c = (Class JavaDoc)cachedClasses.get(name);
375
376         }
377         else
378         {
379             c = loadClassData(name);
380         }
381         
382        
383         return c;
384         /*
385         if (cachedClasses.containsKey( name ))
386         {
387             return (Class)cachedClasses.get(name);
388         }
389         
390         return defineClass(name, b, 0, b.length);
391         */

392     }
393     
394     // From here down is all code copied and pasted from JUnit's
395
// TestCaseClassLoader
396
private Class JavaDoc loadClassData(String JavaDoc className)
397         throws ClassNotFoundException JavaDoc {
398         
399         // 1. Look for cached class...
400

401         // if we can't find the cached class, looking first in no relodable paths...
402

403         byte[] data = null;
404         
405         if (!cachedClasses.containsKey(className))
406         {
407             
408             for (int i = 0; i < fPathChachedItems.size(); i++) {
409             
410             
411                 String JavaDoc path = (String JavaDoc) fPathChachedItems.get(i);
412                 String JavaDoc fileName = className.replace('.', File.separatorChar) + ".class";
413
414
415                 if (isJar(path)) {
416                     //System.out.println("looking for " + fileName.replace(File.separatorChar,'/') + " in jar " +path);
417
data = loadJarData(path, fileName.replace(File.separatorChar,'/'));
418                 } else {
419                     //System.out.println("looking for " + fileName + " in dir " +path);
420
data = loadFileData(path, fileName.replace(File.separatorChar,'/'));
421                 }
422                 if (data != null)
423                 {
424                     Class JavaDoc c = defineClass(className, data, 0, data.length);
425                     cachedClasses.put(className,c);
426                     
427                     return c;
428                 }
429             }
430         }
431         else
432         {
433             return (Class JavaDoc)cachedClasses.get(className);
434         }
435         
436         // Else try to load from reloadable paths...
437
for (int i = 0; i < fPathItems.size(); i++) {
438
439
440                 String JavaDoc path = (String JavaDoc) fPathItems.get(i);
441                 String JavaDoc fileName = className.replace('.', File.separatorChar) + ".class";
442
443                 if (isJar(path)) {
444                     data = loadJarData(path, fileName);
445                 } else {
446                     data = loadFileData(path, fileName);
447                 }
448                 if (data != null)
449                 {
450                     Class JavaDoc c = defineClass(className, data, 0, data.length);
451                     return c;
452                 }
453             }
454
455         throw new ClassNotFoundException JavaDoc(className);
456     }
457
458     boolean isJar(String JavaDoc pathEntry) {
459         return pathEntry.toLowerCase().endsWith(".jar") || pathEntry.toLowerCase().endsWith(".zip");
460     }
461
462     private byte[] loadFileData(String JavaDoc path, String JavaDoc fileName) {
463         File JavaDoc file = new File JavaDoc(path, fileName);
464         //System.out.println("Final class name: " + file.getPath());
465
if (file.exists()) {
466             return getClassData(file);
467         }
468         return null;
469     }
470
471     private byte[] getClassData(File JavaDoc f) {
472         try {
473             FileInputStream JavaDoc stream = new FileInputStream JavaDoc(f);
474             ByteArrayOutputStream JavaDoc out = new ByteArrayOutputStream JavaDoc(1000);
475             byte[] b = new byte[1000];
476             int n;
477             while ((n = stream.read(b)) != -1)
478                 out.write(b, 0, n);
479             stream.close();
480             out.close();
481             return out.toByteArray();
482
483         } catch (IOException JavaDoc e) {
484         }
485         return null;
486     }
487
488     private byte[] loadJarData(String JavaDoc path, String JavaDoc fileName) {
489         ZipFile JavaDoc zipFile = null;
490         InputStream JavaDoc stream = null;
491         File JavaDoc archive = new File JavaDoc(path);
492         if (!archive.exists())
493         {
494             //System.out.println("Il jar non esiste!");
495
return null;
496         }
497         try {
498             zipFile = new ZipFile JavaDoc(archive);
499         } catch (IOException JavaDoc io) {
500             //io.printStackTrace();
501
return null;
502         }
503         
504         //System.out.println("Ricerca entry" + fileName );
505
ZipEntry JavaDoc entry = zipFile.getEntry(fileName);
506         if (entry == null)
507         {
508             //System.out.println("Entry null!");
509
return null;
510         }
511         int size = (int) entry.getSize();
512         try {
513             stream = zipFile.getInputStream(entry);
514             byte[] data = new byte[size];
515             int pos = 0;
516             while (pos < size) {
517                 int n = stream.read(data, pos, data.length - pos);
518                 pos += n;
519             }
520             zipFile.close();
521             return data;
522         } catch (IOException JavaDoc e) {
523         } finally {
524             try {
525                 if (stream != null)
526                     stream.close();
527             } catch (IOException JavaDoc e) {
528                 //e.printStackTrace();
529
}
530         }
531         //System.out.println("Class not found really!");
532
return null;
533     }
534     
535     
536     public Enumeration findResources(String JavaDoc name) {
537         // We have to try to solve the name...
538
Vector urls = new Vector();
539         
540         URL JavaDoc[] pathUrls = new URL JavaDoc[fPathChachedItems.size() + fPathItems.size()];
541         
542         for (int i = 0; i < fPathChachedItems.size(); i++) {
543             String JavaDoc path = (String JavaDoc) fPathChachedItems.get(i);
544             try {
545                 pathUrls[i] = (new File JavaDoc(path)).toURL();
546             } catch (Exception JavaDoc ex)
547             {
548             }
549         }
550         
551         for (int i = 0; i < fPathItems.size(); i++) {
552             String JavaDoc path = (String JavaDoc) fPathItems.get(i);
553             try {
554                 pathUrls[i + fPathChachedItems.size()] = (new File JavaDoc(path)).toURL();
555             } catch (Exception JavaDoc ex)
556             {
557             }
558         }
559         
560         URLClassLoader JavaDoc urlCl = new URLClassLoader JavaDoc(pathUrls, null);
561         try {
562             return urlCl.findResources(name);
563         } catch (Exception JavaDoc ex)
564         {
565             
566         }
567         
568         return new Vector().elements();
569         
570     }
571     
572     public URL JavaDoc findResource(String JavaDoc name) {
573
574         if (name.startsWith("/")) name = name.substring(1);
575         URL JavaDoc[] pathUrls = new URL JavaDoc[fPathChachedItems.size() + fPathItems.size()];
576         
577         for (int i = 0; i < fPathChachedItems.size(); i++) {
578             String JavaDoc path = (String JavaDoc) fPathChachedItems.get(i);
579             try {
580                 pathUrls[i] = (new File JavaDoc(path)).toURL();
581             } catch (Exception JavaDoc ex)
582             {
583             }
584         }
585         
586         for (int i = 0; i < fPathItems.size(); i++) {
587             String JavaDoc path = (String JavaDoc) fPathItems.get(i);
588             try {
589                 pathUrls[i + fPathChachedItems.size()] = (new File JavaDoc(path)).toURL();
590             } catch (Exception JavaDoc ex)
591             {
592             }
593         }
594         
595         URLClassLoader JavaDoc urlCl = new URLClassLoader JavaDoc(pathUrls, null);
596         try {
597             URL JavaDoc url = urlCl.findResource(name);
598             //System.out.println( url);
599
if (url != null) return url;
600         } catch (Exception JavaDoc ex)
601         {
602             ex.printStackTrace();
603         }
604         
605         return ClassLoader.getSystemResource(name);
606         
607     }
608 }
609
Popular Tags