KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > yagga > util > ResourceMgr


1 /*
2  * This file is part of MiniInstaller, a self installer builder for Java
3  * Copyright (C) 2002 Walter Gamba
4  * mailto:walter@yagga.net
5  * http://www.yagga.net/java/miniinstaller
6  *
7  * MiniInstaller is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * MiniInstaller is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  *
21  * As the time of writing, the GNU General Public Licene can be
22  * found at http://www.gnu.org/licenses/gpl.txt
23  *
24  */

25
26 package net.yagga.util;
27
28 import javax.swing.*;
29 import java.io.*;
30 import java.net.*;
31
32 /**
33  *
34 * A class to retrieve resource no matter where they are: on the file system, in a JAR, in
35 * the currently executing JAR or in a JAR inside the currently executing JAR.
36 *
37 * This class can extract resources as ImageIcon, String or raw InputStream, given
38 * a file name, and also classes.
39 *
40 * This class applies to these cases:
41 *
42 * <TABLE BORDER="1">
43 * <TR>
44 * <TD> Where the class that uses ResourceMgr resides </TD>
45 * <TD> Where the Resource file can be </TD>
46 * </TR>
47 * <TR>
48 * <TD> free (as a .class file) </TD>
49 * <TD> in the file system</TD>
50 * </TR>
51 * <TR>
52 * <TD> </TD>
53 * <TD> in a JAR the file system</TD>
54 * </TR>
55 * <TR>
56 * <TD> in a JAR (as a .class in the JAR we are invoking) </TD>
57 * <TD> in the file system (not tested)</TD>
58 * </TR>
59 * <TR>
60 * <TD> </TD>
61 * <TD> in the same JAR as a plain file</TD>
62 * </TR>
63 * <TR>
64 * <TD> in a JAR (as a .class in a JAR we are calling from the JAR we are invoking) </TD>
65 * <TD> in the same JAR as a plain file</TD>
66 * </TR>
67 * <TR>
68 * <TD> </TD>
69 * <TD> in the top level JAR </TD>
70 * </TR>
71 * </TABLE>
72 *
73 * The typical example is if we are executing the JAR below
74 * <PRE>
75 * FOO.jar
76 * +- Main.class
77 * +- Support classes ..
78 * +- BUNDLE1.JAR
79 * +- Display.class
80 * +- ResourceMgr.class
81 * +- IMG/
82 * +- test.gif
83 * </PRE>
84 * If Main.classes uses classes in BUNDLE.jar (loaded with MetaJarClassLoader) and one
85 * such class (Display.class) must load a resource form the same JAR, say IMG/test.gif
86 * it can load it using ResourceMgr.retrieveImageIcon, thus ignoring its execution
87 * environment.
88 *
89 * @see net.yagga.util.MetaJarResources MetaJarResources
90 * @see net.yagga.util.MetaJarClassLoader MetaJarClassLoader
91 *
92 * @author Walter Gamba
93 *
94 */

95 public class ResourceMgr extends ClassLoader JavaDoc{
96
97     /** toggles debugging */
98     public static boolean debug=false;
99
100   /**
101     MetaJarResource used to read meta-jar data.
102   */

103   private static MetaJarResources mjr=null;
104
105   /**
106     retrieve an ImageIcon given a filename.
107
108     The icon can reside quite anywhere: in the file system, in a JAR, even
109     if the calling object resides in a JAR itself, or if it is called
110     inside a JAR jarred inside the top-level executing JAR.<BR/>
111
112         This version of retrieveImageIcon is corrected: now it can read
113         images from:<BR/>
114         1) file system<BR/>
115         2) a jar file <BR/>
116         3) from inside the executing jar<BR/>
117         4) from a jar inside the currently executing jar<BR/>
118
119     @param image the name of the image file. If the name refers to a file
120     or an entry in a JAR/ZIP file, please be sure to specify also the directory, if
121         there is one (speaking relatively...(
122
123     @return the ImageIcon created from the file, or null if errors
124
125         @author Walter Gamba
126   */

127   static public ImageIcon retrieveImageIcon(String JavaDoc image) {
128
129         //first try simple way
130
if(debug)
131                 Ut.infoln("Try with URL getResource with /");
132         URL u=ResourceMgr.class.getResource("/"+image);
133         ImageIcon ii=null;
134         if(u!=null){
135             ii=new ImageIcon(u);
136             if(ii!=null)
137                 return ii;
138       }
139
140     try{
141             if(debug)
142                     Ut.infoln("Try with openResource...");
143             InputStream is=openResource(image);
144
145             int c=-1;
146             byte buf[]=new byte[0];
147             while((c=is.available())>0){
148                 byte b[]=new byte[c];
149                 is.read(b);
150                 byte tmp[]=new byte[buf.length+b.length];
151                 System.arraycopy(buf,0,tmp,0,buf.length);
152                 System.arraycopy(b,0,tmp,buf.length,b.length);
153                 buf=tmp;
154             }
155             if(debug){
156                 System.err.println("READ "+buf.length+"BYTES");
157             }
158
159             ii=new ImageIcon(buf);
160           if(ii!=null)
161         return ii;
162         }catch(IOException ioe){
163             if(debug) Ut.error("Error reading image bytes "+ioe.getMessage());
164         }
165         if(debug) Ut.error("error retieving ImageIcon" );
166         return null;
167   }
168
169   static public ImageIcon retrieveImageIcon2(String JavaDoc image) {
170     try{
171             if(debug)
172                 Ut.infoln("Try 2 with getResource with /");
173       ImageIcon ii=new ImageIcon(ResourceMgr.class.getResource("/"+image));
174       ii.getIconHeight();
175       return ii;
176     }catch(NullPointerException JavaDoc npe){
177       try{
178             if(debug)
179                 Ut.infoln("Try 2 with MetaJarClassLoader");
180       if(mjr==null){
181         //I must try to get this jar's name
182
ResourceMgr rm=new ResourceMgr();
183         ClassLoader JavaDoc cl=ResourceMgr.class.getClassLoader();
184         String JavaDoc jarFile="";
185         if(cl instanceof BootstrapJarClassLoader){
186           jarFile=((BootstrapJarClassLoader)cl).getActualJarName();
187                   Ut.infoln("BootstrapJarClassLoader: retrieving image:'"+image+"'");
188                 }
189         mjr = new MetaJarResources(jarFile);
190       }
191       byte b[]=mjr.getBytes(image);
192       ImageIcon ii=new ImageIcon(b);
193
194       //to generate a null pointer
195
ii.getIconHeight();
196       //Ut.error("RM1 nota: retrieving image:'"+image+"':"+ii+":"+ ii.getIconHeight());
197
return ii;
198       }catch(NullPointerException JavaDoc npe2){
199         Ut.error("RM1b: retrieving image:'"+image+"'");
200       }
201     }
202     return null;
203   }
204
205
206   /**
207     retrieve a (text) file as a String. Only suited to read text files.
208
209     The file can reside quite anywhere: in the file system, in a JAR, even
210     if the calling object resides in a JAR itself, or if it is called
211     inside a JAR jarred inside the top-level executing JAR.
212
213     @param fileName the name of the (text) file. If the name refers to a file
214     or an entry in a JAR/ZIP file, please be sure to specify also the directory.
215
216     @return the String containig the lines of the file
217   */

218   public static String JavaDoc retrieveFile(String JavaDoc fileName){
219         String JavaDoc file="",line="";
220     try{
221             Reader r=new InputStreamReader(openResource(fileName));
222             BufferedReader read=new BufferedReader(r);
223             while((line=read.readLine())!=null){
224         file+=line+Ut.nl;
225       }
226       r.close();
227     }
228     catch(IOException ioe){
229       Ut.error("RM1: reading (resource) file '"+fileName+"':"+ioe);
230       return "";
231     }
232     return file;
233   }
234
235
236
237   /**
238     gets the InputSream associated with a given file. Use this method to read
239     raw data from a resource
240
241     The file can reside quite anywhere: in the file system, in a JAR, even
242     if the calling object resides in a JAR itself, or if it is called
243     inside a JAR jarred inside the top-level executing JAR.
244
245     @param fileName the name of the file. If the name refers to a file
246     or an entry in a JAR/ZIP file, please be sure to specify also the directory.
247
248     @return the InputStream associated with the file.
249   */

250   static public InputStream openResource(String JavaDoc filename)
251     {
252
253         try
254         {
255             if(debug)
256                 Ut.infoln("read as simple resource with /");
257
258
259       InputStream is=ResourceMgr.class.getResourceAsStream("/"+filename);
260       is.available();//to generate null ptr exceptio
261
return is;
262         }
263         catch (java.io.IOException JavaDoc e)
264         {
265             Ut.error("RM1: file not found:"+filename);
266             return null;
267         }
268         catch(NullPointerException JavaDoc e2){
269             if(debug)
270                 Ut.infoln("read as simple resource w/o /");
271       //maybe it's just out there...
272
InputStream is= ResourceMgr.class.getResourceAsStream(filename);
273             if(is==null)
274       {
275         try{
276                     if(debug)
277                           Ut.infoln("read as file");
278            is= new FileInputStream(filename);
279         }
280         catch(FileNotFoundException fnfe)
281         {
282                     if(debug)
283                   Ut.infoln("Now read bytes from class loader");
284
285           try{
286           if(mjr==null){
287             //I must try to get this jar's name
288
ResourceMgr rm=new ResourceMgr();
289             ClassLoader JavaDoc cl=ResourceMgr.class.getClassLoader();
290             String JavaDoc jarFile="";
291             if(cl instanceof BootstrapJarClassLoader)
292               jarFile=((BootstrapJarClassLoader)cl).getActualJarName();
293                         mjr = new MetaJarResources(jarFile);
294           }
295           byte b[]=mjr.getBytes(filename);
296           //Ut.infoln("RM1: getting bytes for:"+filename+" from jar ");
297

298           is=new ByteArrayInputStream(b);
299
300           //to generate a null pointer
301
is.available();
302           //Ut.error("RM1 nota: retrieving image:'"+image+"':"+ii+":"+ ii.getIconHeight());
303
return is;
304           }catch(IOException npe2){
305             Ut.error("RM1cb: retrieving stream:'"+filename+"'");
306           }catch(NullPointerException JavaDoc npe2){
307             Ut.error("RM1b: retrieving stream:'"+filename+"'");
308           }
309                   //if cant' find in FileSystem in Jar that is executing.. maybe from Inside another
310
//jar, then try intermediate find.. we are looking for sthing
311
//located in the top level executing jar, but not in the nested jar..
312
try{
313                     is=Runtime.getRuntime().getClass().getResourceAsStream(filename);
314                     if(is==null)
315                         is=Runtime.getRuntime().getClass().getResourceAsStream("/"+filename);
316                  is.available();
317                  return is;
318                 }catch(IOException ioe){
319                     Ut.error("RM1c: retrieving local stream:'"+filename+"'");
320                 }catch(NullPointerException JavaDoc npe2){
321             Ut.error("RM1c1: retrieving stream:'"+filename+"'");
322           }
323                     catch(Exception JavaDoc e){
324                 Ut.error("RM1c3: retrieving stream:'"+filename+"'");
325                 }
326
327         // System.exit(1);
328
return null;
329         }
330         return is;
331       }
332       else
333         return is;
334         }
335     // return null;
336
}
337
338     public static Class JavaDoc retrieveClass(String JavaDoc className) throws ClassNotFoundException JavaDoc
339     {
340         ResourceMgr rm=new ResourceMgr();
341         return rm.findClass(className);
342     }
343
344     /**
345      * Method that reads the class from everywhere, file system jarred inside me etc..
346      * This method uses MetaJarResources to read raw bytes, then creates a Class
347      * with the given bytes
348      * @param className the classname (fully qualified with "."). Teh name is then read
349      * friom the jar file substituting "." with "/" and appending ".class"
350      * @return a Class object of representing the given class
351      */

352     protected Class JavaDoc findClass(String JavaDoc className) throws ClassNotFoundException JavaDoc
353     {
354         //try simpelst mthod firs
355
try{
356             return Class.forName(className);
357         }catch(ClassNotFoundException JavaDoc cnfe){
358             if(debug)
359                 Ut.infoln("cant' find in simple way");
360         }
361
362         String JavaDoc urlName=className.replace('.', '/') + ".class";
363 /*
364         //try second simplest mthod
365         try{
366             URL u=ResourceMgr.class.getResource("/"+urlName);
367             Ut.infoln("URL of "+urlName+" = "+u);
368             return Class.forName(className);
369         }catch(ClassNotFoundException cnfe){
370             if(debug)
371                 Ut.infoln("cant' find in second simple way");
372         }
373 */

374             //if it doesn't find class, perhaps we
375
//are being called from inside a JAR file
376
//and class file resides on the file system
377
//parallel to the jar file :
378
// dir layout:
379
// test/
380
// +- executing.jar
381
// += MyClass.clas
382
//and command line was
383
// java -jar executing.jar
384
//and inside executing.jar code there
385
//is a call to loadClass("MyClass")
386
try{
387              //read bytes....
388
InputStream is=openResource(urlName);
389           int c=-1;
390             byte buf[]=new byte[0];
391             while((c=is.available())>0){
392                 byte b[]=new byte[c];
393                 is.read(b);
394                 byte tmp[]=new byte[buf.length+b.length];
395                 System.arraycopy(buf,0,tmp,0,buf.length);
396                 System.arraycopy(b,0,tmp,buf.length,b.length);
397                 buf=tmp;
398             }
399             return defineClass(className,buf,0,buf.length);
400         }
401         catch(IOException ioe){
402             Ut.error("Errore IO:"+ioe);
403         }catch(ClassFormatError JavaDoc cfe){
404             Ut.error("'"+className+"':"+cfe);
405         }
406         throw new ClassNotFoundException JavaDoc("Can't find class '"+className+"'");
407     }
408     /**
409      * Write a String in HEXadecimal format.
410      * Output format is<BR/>
411      * <CODE>
412      * 'a' = 0x0060 <BR/>
413      * 'b' = 0x0061 <BR/>
414      * </CODE>
415      * Between lines the paraemter "newLineSep"is written.<BR>
416      * @param orig string to decode
417      * @param prefix a prefix for every "line"
418      * @param newLineSep string to use as line-separator
419      * @return decoded string (useful for debugging)
420      */

421     public static String JavaDoc toHexString(byte[] orig, String JavaDoc prefix, String JavaDoc newLineSep, int limit){
422         StringBuffer JavaDoc sb=new StringBuffer JavaDoc();
423         int len=limit> orig.length ? orig.length : limit;
424         for(int i=0;i<len;i++){
425             byte c=orig[i];
426             sb.append(prefix).append("'").append(c).append("' = ").append(Integer.toHexString(c)).append(newLineSep);
427         }
428         return sb.toString();
429     }
430
431 }
Popular Tags