1 17 package org.apache.geronimo.deployment.util; 18 19 import java.io.File ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.util.Collection ; 23 import java.util.Collections ; 24 import java.util.Enumeration ; 25 import java.util.Iterator ; 26 import java.util.LinkedList ; 27 import java.util.jar.JarEntry ; 28 import java.util.jar.JarFile ; 29 import java.util.jar.Manifest ; 30 import java.util.zip.ZipEntry ; 31 32 35 public class NestedJarFile extends JarFile { 36 private JarFile baseJar; 37 private String basePath; 38 private boolean isClosed = false; 39 private boolean manifestLoaded = false; 40 private Manifest manifest; 41 private File tempFile; 42 43 public NestedJarFile(JarFile jarFile, String path) throws IOException { 44 super(DeploymentUtil.DUMMY_JAR_FILE); 45 46 JarEntry targetEntry = jarFile.getJarEntry(path + "/"); 48 if (targetEntry == null) { 49 targetEntry = jarFile.getJarEntry(path); 50 if (targetEntry == null) { 51 throw new IOException ("Jar entry does not exist: jarFile=" + jarFile.getName() + ", path=" + path); 52 } 53 } 54 55 if (targetEntry.isDirectory()) { 56 baseJar = jarFile; 57 if (!path.endsWith("/")) { 58 path += "/"; 59 } 60 basePath = path; 61 } else { 62 if (targetEntry instanceof UnpackedJarEntry) { 63 File targetFile = ((UnpackedJarEntry) targetEntry).getFile(); 67 baseJar = new JarFile (targetFile); 68 basePath = ""; 69 } else { 70 tempFile = DeploymentUtil.toFile(jarFile, targetEntry.getName()); 71 baseJar = new JarFile (tempFile); 72 basePath = ""; 73 } 74 } 75 } 76 77 public boolean isUnpacked() { 78 if (isClosed) { 79 throw new IllegalStateException ("NestedJarFile is closed"); 80 } 81 return basePath.length() > 0; 82 } 83 84 public boolean isPacked() { 85 if (isClosed) { 86 throw new IllegalStateException ("NestedJarFile is closed"); 87 } 88 return basePath.length() == 0; 89 } 90 91 public JarFile getBaseJar() { 92 if (isClosed) { 93 throw new IllegalStateException ("NestedJarFile is closed"); 94 } 95 return baseJar; 96 } 97 98 public String getBasePath() { 99 if (isClosed) { 100 throw new IllegalStateException ("NestedJarFile is closed"); 101 } 102 return basePath; 103 } 104 105 public Manifest getManifest() throws IOException { 106 if (isClosed) { 107 throw new IllegalStateException ("NestedJarFile is closed"); 108 } 109 110 if (!manifestLoaded) { 111 JarEntry manifestEntry = getBaseEntry("META-INF/MANIFEST.MF"); 112 113 if (manifestEntry != null && !manifestEntry.isDirectory()) { 114 InputStream in = null; 115 try { 116 in = baseJar.getInputStream(manifestEntry); 117 manifest = new Manifest (in); 118 } finally { 119 if (in != null) { 120 try { 121 in.close(); 122 } catch (IOException e) { 123 } 125 } 126 } 127 } 128 manifestLoaded = true; 129 } 130 return manifest; 131 } 132 133 public NestedJarEntry getNestedJarEntry(String name) { 134 if (isClosed) { 135 throw new IllegalStateException ("NestedJarFile is closed"); 136 } 137 138 JarEntry baseEntry = getBaseEntry(name); 139 if (baseEntry == null) { 140 return null; 141 } 142 return new NestedJarEntry(name, baseEntry, getManifestSafe()); 143 } 144 145 public JarEntry getJarEntry(String name) { 146 if (isClosed) { 147 throw new IllegalStateException ("NestedJarFile is closed"); 148 } 149 150 return getNestedJarEntry(name); 151 } 152 153 public ZipEntry getEntry(String name) { 154 if (isClosed) { 155 throw new IllegalStateException ("NestedJarFile is closed"); 156 } 157 158 return getNestedJarEntry(name); 159 } 160 161 public Enumeration entries() { 162 if (isClosed) { 163 throw new IllegalStateException ("NestedJarFile is closed"); 164 } 165 166 Collection baseEntries = Collections.list(baseJar.entries()); 167 Collection entries = new LinkedList (); 168 for (Iterator iterator = baseEntries.iterator(); iterator.hasNext();) { 169 JarEntry baseEntry = (JarEntry ) iterator.next(); 170 String path = baseEntry.getName(); 171 if (path.startsWith(basePath)) { 172 entries.add(new NestedJarEntry(path.substring(basePath.length()), baseEntry, getManifestSafe())); 173 } 174 } 175 return Collections.enumeration(entries); 176 } 177 178 public InputStream getInputStream(ZipEntry zipEntry) throws IOException { 179 if (isClosed) { 180 throw new IllegalStateException ("NestedJarFile is closed"); 181 } 182 183 JarEntry baseEntry; 184 if (zipEntry instanceof NestedJarEntry) { 185 baseEntry = ((NestedJarEntry)zipEntry).getBaseEntry(); 186 } else { 187 baseEntry = getBaseEntry(zipEntry.getName()); 188 } 189 190 if (baseEntry == null) { 191 throw new IOException ("Entry not found: name=" + baseEntry.getName()); 192 } else if (baseEntry.isDirectory()) { 193 return new DeploymentUtil.EmptyInputStream(); 194 } 195 return baseJar.getInputStream(baseEntry); 196 } 197 198 public String getName() { 199 return baseJar.getName(); 200 } 201 202 206 public int size() { 207 if (isClosed) { 208 throw new IllegalStateException ("NestedJarFile is closed"); 209 } 210 return -1; 211 } 212 213 public void close() throws IOException { 214 if (isClosed) { 215 return; 216 } 217 218 try { 219 if (baseJar != null && isPacked()) { 220 baseJar.close(); 221 } 222 } finally { 223 isClosed = true; 224 baseJar = null; 225 basePath = null; 226 manifestLoaded = false; 227 manifest = null; 228 if (tempFile != null) { 229 tempFile.delete(); 230 tempFile = null; 231 } 232 } 233 } 234 235 protected void finalize() throws IOException { 236 close(); 237 } 238 239 private JarEntry getBaseEntry(String name) { 240 return baseJar.getJarEntry(basePath + name); 241 } 242 243 private Manifest getManifestSafe() { 244 Manifest manifest = null; 245 try { 246 manifest = getManifest(); 247 } catch (IOException e) { 248 } 250 return manifest; 251 } 252 253 } 254 | Popular Tags |