1 4 package org.jboss.virtual.plugins.context.jar; 5 6 import org.jboss.virtual.plugins.context.AbstractVirtualFileHandler; 7 import org.jboss.virtual.spi.VFSContext; 8 import org.jboss.virtual.spi.VirtualFileHandler; 9 10 import java.io.ByteArrayInputStream ; 11 import java.io.ByteArrayOutputStream ; 12 import java.io.FileNotFoundException ; 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.net.MalformedURLException ; 16 import java.net.URI ; 17 import java.net.URISyntaxException ; 18 import java.net.URL ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.ArrayList ; 23 import java.util.zip.ZipEntry ; 24 import java.util.zip.ZipInputStream ; 25 26 32 public class NestedJarFromStream 33 extends AbstractVirtualFileHandler 34 { 35 36 private static final long serialVersionUID = 1L; 37 38 private ZipInputStream zis; 39 private HashMap <String , JarEntryContents> entries = new HashMap <String , JarEntryContents>(); 40 private URL jarURL; 41 private URL entryURL; 42 private String vfsPath; 43 private String name; 44 private long lastModified; 45 private long size; 46 private boolean inited; 47 48 56 public NestedJarFromStream(VFSContext context, VirtualFileHandler parent, ZipInputStream zis, URL jarURL, ZipEntry entry) 57 { 58 super(context, parent, entry.getName()); 59 this.jarURL = jarURL; 60 this.name = entry.getName(); 61 this.lastModified = entry.getTime(); 62 this.size = entry.getSize(); 63 this.zis = zis; 64 } 65 66 67 public VirtualFileHandler findChild(String path) throws IOException 68 { 69 if( inited == false ) 70 init(); 71 return entries.get(name); 72 } 73 74 public List <VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException 75 { 76 if( inited == false ) 77 init(); 78 List <VirtualFileHandler> children = new ArrayList <VirtualFileHandler>(); 79 children.addAll(entries.values()); 80 return children; 81 } 82 83 public boolean isLeaf() throws IOException 84 { 85 return false; 86 } 87 88 public boolean isHidden() 89 { 90 return false; 91 } 92 93 public long getSize() 94 { 95 return size; 96 } 97 98 public long getLastModified() throws IOException 99 { 100 return lastModified; 101 } 102 103 104 public Iterator <JarEntryContents> getEntries() 105 throws IOException 106 { 107 if( inited == false ) 108 init(); 109 return entries.values().iterator(); 110 } 111 public JarEntryContents getEntry(String name) 112 throws IOException 113 { 114 if( inited == false ) 115 init(); 116 return entries.get(name); 117 } 118 public ZipEntry getJarEntry(String name) 119 throws IOException 120 { 121 if( inited == false ) 122 init(); 123 JarEntryContents jec = entries.get(name); 124 return (jec != null ? jec.getEntry() : null); 125 } 126 public byte[] getContents(String name) 127 throws IOException 128 { 129 if( inited == false ) 130 init(); 131 JarEntryContents jec = entries.get(name); 132 return (jec != null ? jec.getContents() : null); 133 } 134 135 public String getName() 136 { 137 return name; 138 } 139 public String getPathName() 140 { 141 return vfsPath; 142 } 143 144 public InputStream openStream() throws IOException 146 { 147 return zis; 148 } 149 150 public void close() 151 { 152 entries.clear(); 153 if( zis != null ) 154 { 155 try 156 { 157 zis.close(); 158 } 159 catch(IOException e) 160 { 161 log.error("close error", e); 162 } 163 zis = null; 164 } 165 } 166 167 public URI toURI() throws URISyntaxException 168 { 169 try 170 { 171 if( entryURL == null ) 172 entryURL = new URL (jarURL, getName()); 173 } 174 catch(MalformedURLException e) 175 { 176 throw new URISyntaxException ("Failed to create relative jarURL", e.getMessage()); 177 } 178 return entryURL.toURI(); 179 } 180 181 public String toString() 182 { 183 StringBuffer tmp = new StringBuffer (super.toString()); 184 tmp.append('['); 185 tmp.append("name="); 186 tmp.append(getName()); 187 tmp.append(",size="); 188 tmp.append(getSize()); 189 tmp.append(",lastModified="); 190 tmp.append(lastModified); 191 tmp.append(",URI="); 192 try 193 { 194 tmp.append(toURI()); 195 } 196 catch(URISyntaxException e) 197 { 198 } 199 tmp.append(']'); 200 return tmp.toString(); 201 } 202 203 protected void init() 204 throws IOException 205 { 206 inited = true; 207 ZipEntry entry = zis.getNextEntry(); 208 while( entry != null ) 209 { 210 try 211 { 212 String url = toURI().toASCIIString() + "!/" + entry.getName(); 213 URL jecURL = new URL (url); 214 JarEntryContents jec = new JarEntryContents(getVFSContext(), this, entry, jecURL, zis, getPathName()); 215 entries.put(entry.getName(), jec); 216 entry = zis.getNextEntry(); 217 } 218 catch(URISyntaxException e) 219 { 220 e.printStackTrace(); 221 } 222 } 223 zis.close(); 224 zis = null; 225 } 226 227 public static class JarEntryContents 228 extends AbstractVirtualFileHandler 229 { 230 231 private static final long serialVersionUID = 1L; 232 private ZipEntry entry; 233 private URL entryURL; 234 private String vfsPath; 235 private byte[] contents; 236 private boolean isJar; 237 private NestedJarFromStream njar; 238 private InputStream openStream; 239 240 JarEntryContents(VFSContext context, VirtualFileHandler parent, ZipEntry entry, URL entryURL, InputStream zis, 241 String parentVfsPath) 242 throws IOException 243 { 244 super(context, parent, entry.getName()); 245 this.entry = entry; 246 this.entryURL = entryURL; 247 this.vfsPath = parentVfsPath + "/" + entry.getName(); 248 this.isJar = JarUtils.isArchive(entry.getName()); 249 int size = (int) entry.getSize(); 250 if( size <= 0 ) 251 return; 252 253 ByteArrayOutputStream baos = new ByteArrayOutputStream (size); 254 byte[] tmp = new byte[1024]; 255 while( zis.available() > 0 ) 256 { 257 int length = zis.read(tmp); 258 if( length > 0 ) 259 baos.write(tmp, 0, length); 260 } 261 contents = baos.toByteArray(); 262 } 263 264 public boolean isHidden() throws IOException 265 { 266 return false; 267 } 268 269 public ZipEntry getEntry() 270 { 271 return entry; 272 } 273 public byte[] getContents() 274 { 275 return contents; 276 } 277 278 public String getName() 279 { 280 return entry.getName(); 281 } 282 public String getPathName() 283 { 284 return vfsPath; 285 } 286 287 public List <VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException 288 { 289 List <VirtualFileHandler> children = null; 290 if( isJar ) 291 { 292 initNestedJar(); 293 children = njar.getChildren(ignoreErrors); 294 } 295 return children; 296 } 297 public VirtualFileHandler findChild(String path) throws IOException 298 { 299 VirtualFileHandler child; 300 if( isJar ) 301 { 302 initNestedJar(); 303 child = njar.findChild(path); 304 } 305 else 306 { 307 throw new FileNotFoundException ("JarEntryContents("+entry.getName()+") has no children"); 308 } 309 return child; 310 } 311 312 public long getLastModified() 314 { 315 return entry.getTime(); 316 } 317 318 public long getSize() 319 { 320 return entry.getSize(); 321 } 322 323 public boolean isLeaf() 324 { 325 if (isJar) 326 return false; 327 return entry.isDirectory() == false; 328 } 329 330 public synchronized InputStream openStream() 332 throws IOException 333 { 334 initNestedJar(); 335 if( njar != null ) 336 openStream = njar.openStream(); 337 else 338 openStream = new ByteArrayInputStream (contents); 339 return openStream; 340 } 341 342 public synchronized void close() 343 { 344 if( openStream != null ) 345 { 346 try 347 { 348 openStream.close(); 349 } 350 catch(IOException e) 351 { 352 log.error("close error", e); 353 } 354 openStream = null; 355 } 356 } 357 358 public URI toURI() throws URISyntaxException 359 { 360 return entryURL.toURI(); 361 } 362 363 public String toString() 364 { 365 StringBuffer tmp = new StringBuffer (super.toString()); 366 tmp.append('['); 367 tmp.append("name="); 368 tmp.append(entry.getName()); 369 tmp.append(",size="); 370 tmp.append(entry.getSize()); 371 tmp.append(",time="); 372 tmp.append(entry.getTime()); 373 tmp.append(",URI="); 374 try 375 { 376 tmp.append(toURI()); 377 } 378 catch(URISyntaxException e) 379 { 380 } 381 tmp.append(']'); 382 return tmp.toString(); 383 } 384 385 private synchronized void initNestedJar() 386 throws IOException 387 { 388 if( isJar && njar == null ) 389 { 390 ByteArrayInputStream bais = new ByteArrayInputStream (contents); 391 ZipInputStream zis = new ZipInputStream (bais); 392 njar = new NestedJarFromStream(getVFSContext(), this, zis, entryURL, entry); 393 } 394 } 395 } 396 } 397 | Popular Tags |