001 ///////////////////////////////////////////////// 002 // This file is part of Sears project. 003 // Subtitle Editor And Re-Synch 004 // A tool to easily modify and resynch movies subtitles. 005 ///////////////////////////////////////////////// 006 //This program is free software; 007 //you can redistribute it and/or modify it under the terms 008 //of the GNU General Public License 009 //as published by the Free Software Foundation; 010 //either version 2 of the License, or (at your option) any later version. 011 ///////////////////////////////////////////////// 012 //Sears project is availbale under sourceforge 013 // at adress: http://sourceforge.net/projects/sears/ 014 //Copyright (C) 2005 Booba Skaya 015 //Mail: booba.skaya@gmail.com 016 //////////////////////////////////////////////// 017 package sears.tools; 018 019 import java.io.*; 020 import java.util.*; 021 import java.util.zip.*; 022 023 /** 024 * JarResources: JarResources maps all resources included in a Zip or Jar file. 025 * Additionaly, it provides a method to extract one as a blob. 026 */ 027 public final class JarResources { 028 029 // external debug flag 030 public boolean debugOn = false; 031 032 // jar resource mapping tables 033 private Hashtable<String, Integer> htSizes = new Hashtable<String, Integer>(); 034 035 private Hashtable<String, byte[]> htJarContents = new Hashtable<String, byte[]>(); 036 037 // a jar file 038 private String jarFileName; 039 040 /** 041 * creates a JarResources. It extracts all resources from a Jar into an 042 * internal hashtable, keyed by resource names. 043 * 044 * @param jarFileName 045 * a jar or zip file 046 */ 047 public JarResources(String jarFileName) { 048 this.jarFileName = jarFileName; 049 init(); 050 } 051 052 /** 053 * Extracts a jar resource as a blob. 054 * 055 * @param name 056 * a resource name. 057 */ 058 public byte[] getResource(String name) { 059 return (byte[]) htJarContents.get(name); 060 } 061 062 /** 063 * initializes internal hash tables with Jar file resources. 064 */ 065 private void init() { 066 try { 067 // extracts just sizes only. 068 ZipFile zf = new ZipFile(jarFileName); 069 Enumeration e = zf.entries(); 070 while (e.hasMoreElements()) { 071 ZipEntry ze = (ZipEntry) e.nextElement(); 072 if (debugOn) { 073 System.out.println(dumpZipEntry(ze)); 074 } 075 htSizes.put(ze.getName(), new Integer((int) ze.getSize())); 076 } 077 zf.close(); 078 079 // extract resources and put them into the hashtable. 080 FileInputStream fis = new FileInputStream(jarFileName); 081 BufferedInputStream bis = new BufferedInputStream(fis); 082 ZipInputStream zis = new ZipInputStream(bis); 083 ZipEntry ze = null; 084 while ((ze = zis.getNextEntry()) != null) { 085 if (ze.isDirectory()) { 086 continue; 087 } 088 if (debugOn) { 089 System.out.println("ze.getName()=" + ze.getName() + "," 090 + "getSize()=" + ze.getSize()); 091 } 092 int size = (int) ze.getSize(); 093 // -1 means unknown size. 094 if (size == -1) { 095 size = ((Integer) htSizes.get(ze.getName())).intValue(); 096 } 097 byte[] b = new byte[(int) size]; 098 int rb = 0; 099 int chunk = 0; 100 while (((int) size - rb) > 0) { 101 chunk = zis.read(b, rb, (int) size - rb); 102 if (chunk == -1) { 103 break; 104 } 105 rb += chunk; 106 } 107 // add to internal resource hashtable 108 htJarContents.put(ze.getName(), b); 109 if (debugOn) { 110 System.out.println(ze.getName() + " rb=" + rb + ",size=" 111 + size + ",csize=" + ze.getCompressedSize()); 112 } 113 } 114 } catch (NullPointerException e) { 115 System.out.println("done."); 116 } catch (FileNotFoundException e) { 117 e.printStackTrace(); 118 } catch (IOException e) { 119 e.printStackTrace(); 120 } 121 } 122 123 /** 124 * Dumps a zip entry into a string. 125 * 126 * @param ze 127 * a ZipEntry 128 */ 129 private String dumpZipEntry(ZipEntry ze) { 130 StringBuffer sb = new StringBuffer(); 131 if (ze.isDirectory()) { 132 sb.append("d "); 133 } else { 134 sb.append("f "); 135 } 136 if (ze.getMethod() == ZipEntry.STORED) { 137 sb.append("stored "); 138 } else { 139 sb.append("defalted "); 140 } 141 sb.append(ze.getName()); 142 sb.append("\t"); 143 sb.append("" + ze.getSize()); 144 if (ze.getMethod() == ZipEntry.DEFLATED) { 145 sb.append("/" + ze.getCompressedSize()); 146 } 147 return (sb.toString()); 148 } 149 150 /** 151 * Is a test driver. Given a jar file and a resource name, it trys to 152 * extract the resource and then tells us whether it could or not. 153 * 154 * <strong>Example</strong> Let's say you have a JAR file which jarred up a 155 * bunch of gif image files. Now, by using JarResources, you could extract, 156 * create, and display those images on-the-fly. 157 * 158 * <pre> 159 * ... 160 * JarResources JR=new JarResources("GifBundle.jar"); 161 * Image image=Toolkit.createImage(JR.getResource("logo.gif"); 162 * Image logo=Toolkit.getDefaultToolkit().createImage( 163 * JR.getResources("logo.gif") 164 * ); 165 * ... 166 * </pre> 167 */ 168 public static void main(String[] args) throws IOException { 169 if (args.length != 2) { 170 System.err 171 .println("usage: java JarResources <jar file name> <resource name>"); 172 System.exit(1); 173 } 174 JarResources jr = new JarResources(args[0]); 175 byte[] buff = jr.getResource(args[1]); 176 if (buff == null) { 177 System.out.println("Could not find " + args[1] + "."); 178 } else { 179 System.out.println("Found " + args[1] + " (length=" + buff.length 180 + ")."); 181 } 182 } 183 184 } // End of JarResources class. 185