View Javadoc

1   package org.wcb.common;
2   /***
3    * Copyright (C) 1999  Walter Bogaardt
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
18   *
19   */
20  import java.io.IOException;
21  import java.io.FileNotFoundException;
22  import java.io.FileInputStream;
23  import java.io.BufferedInputStream;
24  import java.util.Hashtable;
25  import java.util.Enumeration;
26  import java.util.zip.ZipEntry;
27  import java.util.zip.ZipFile;
28  import java.util.zip.ZipInputStream;
29  import java.awt.Image;
30  import java.awt.Toolkit;
31  
32  /***
33   * JarResources: JarResources maps all resources included in a
34   * Zip or Jar file. Additionaly, it provides a method to extract one
35   * as a blob.
36   */
37  public final class JarResources {
38  
39     // external debug flag
40     public boolean debugOn=false;
41  
42     // jar resource mapping tables
43     private Hashtable htSizes=new Hashtable();  
44     private Hashtable htJarContents=new Hashtable();
45     private String jarFileName;
46     private static String DEFAULTFILENAME = "alice.jar";
47     private String SEP = System.getProperty("file.separator");
48     private String directory;
49  
50     public JarResources(){
51          this(DEFAULTFILENAME);
52      }       
53  
54      public JarResources(String fileName)
55      {
56          this(null, fileName);
57      }
58      
59     /***
60      * creates a JarResources. It extracts all resources from a Jar
61      * into an internal hashtable, keyed by resource names.
62      * @param jarFileName a jar or zip file
63      */
64     public JarResources(String dir, String jarFileName) {
65        if(null==dir)
66            directory = System.getProperty("user.dir");   
67        this.jarFileName=directory+SEP+jarFileName;
68        //init();
69     }
70  
71     /***
72      * Extracts a jar resource as a blob.
73      * @param name a resource name.
74      */
75     public byte[] getResource(String name) {
76        return (byte[])htJarContents.get(name);
77     }
78  
79      public Image getImage(String imgName) {
80          return Toolkit.getDefaultToolkit().createImage(JarResources.class.getResource("/"+imgName));
81      }
82         
83     /***
84      * initializes internal hash tables with Jar file resources.
85      */
86     private void init() {
87        try {
88            readFile(jarFileName);
89        } catch(FileNotFoundException err){
90            try{
91              readFile(System.getProperty("user.home")+SEP+DEFAULTFILENAME);
92            }catch(Exception er){
93            }
94        } catch(IOException err){
95             try{
96              readFile(System.getProperty("user.home")+SEP+DEFAULTFILENAME);
97            }catch(Exception er){
98            }
99        } finally{
100       }
101    }
102    
103    private void readFile(String filename) throws FileNotFoundException, IOException{
104         try {
105           // extracts just sizes only. 
106           ZipFile zf=new ZipFile(filename);
107           Enumeration e=zf.entries();
108           while (e.hasMoreElements()) {
109               ZipEntry ze=(ZipEntry)e.nextElement();
110               if (debugOn) {
111                  System.out.println(dumpZipEntry(ze));
112               }
113               htSizes.put(ze.getName(),new Integer((int)ze.getSize()));
114           }
115           zf.close();
116 
117           // extract resources and put them into the hashtable.
118           FileInputStream fis=new FileInputStream(filename);
119           BufferedInputStream bis=new BufferedInputStream(fis);
120           ZipInputStream zis=new ZipInputStream(bis);
121           ZipEntry ze=null;
122           while ((ze=zis.getNextEntry())!=null) {
123              if (ze.isDirectory()) {
124                 continue;
125              }
126              if (debugOn) {
127                 System.out.println(
128                    "ze.getName()="+ze.getName()+","+"getSize()="+ze.getSize()
129                    );
130              }
131              int size=(int)ze.getSize();
132              // -1 means unknown size. 
133              if (size==-1) {
134                 size=((Integer)htSizes.get(ze.getName())).intValue();
135              }
136              byte[] b=new byte[size];
137              int rb=0;
138              int chunk=0;
139              while ((size - rb) > 0) {
140                  chunk=zis.read(b,rb,size - rb);
141                  if (chunk==-1) {
142                     break;
143                  }
144                  rb+=chunk;
145              }
146              // add to internal resource hashtable
147              htJarContents.put(ze.getName(),b);
148              if (debugOn) {
149                 System.out.println(
150                    ze.getName()+"  rb="+rb+
151                    ",size="+size+
152                    ",csize="+ze.getCompressedSize()
153                    );
154              }
155           }
156        } catch (NullPointerException e) {
157           System.out.println("done.");
158        } catch (FileNotFoundException e) {
159           throw new FileNotFoundException(e.toString());
160        } catch (IOException e) {
161           throw new IOException(e.toString());
162        }
163    }
164 
165    /***
166     * Dumps a zip entry into a string.
167     * @param ze a ZipEntry
168     */
169    private String dumpZipEntry(ZipEntry ze) {
170        StringBuffer sb=new StringBuffer();
171        if (ze.isDirectory()) {
172           sb.append("d "); 
173        } else {
174           sb.append("f "); 
175        }
176        if (ze.getMethod()==ZipEntry.STORED) {
177           sb.append("stored   "); 
178        } else {
179           sb.append("defalted ");
180        }
181        sb.append(ze.getName());
182        sb.append("\t");
183        sb.append(""+ze.getSize());
184        if (ze.getMethod()==ZipEntry.DEFLATED) {
185           sb.append("/"+ze.getCompressedSize());
186        }
187        return (sb.toString());
188    }
189 
190    /***
191     * Is a test driver. Given a jar file and a resource name, it trys to
192     * extract the resource and then tells us whether it could or not.
193     *
194     * <strong>Example</strong>
195     * Let's say you have a JAR file which jarred up a bunch of gif image
196     * files. Now, by using JarResources, you could extract, create, and display
197     * those images on-the-fly.
198     * <pre>
199     *     ...
200     *     JarResources JR=new JarResources("GifBundle.jar");
201     *     Image image=Toolkit.createImage(JR.getResource("logo.gif");
202     *     Image logo=Toolkit.getDefaultToolkit().createImage(
203     *                   JR.getResources("logo.gif")
204     *                   );
205     *     ...
206     * </pre>
207     */
208    public static void main(String[] args) {
209        if (args.length!=2) {
210           System.err.println(
211              "usage: java JarResources <jar file name> <resource name>"
212              );
213           System.exit(1);
214        }
215        JarResources jr=new JarResources(args[0]);
216        byte[] buff=jr.getResource(args[1]);
217        if (buff==null) {
218           System.out.println("Could not find "+args[1]+".");
219        } else {
220           System.out.println("Found "+args[1]+ " (length="+buff.length+").");
221        }
222    }
223 
224 }	// End of JarResources class.