1 22 package org.jboss.virtual.plugins.context.jar; 23 24 import java.io.FileNotFoundException ; 25 import java.io.IOException ; 26 import java.io.ObjectInputStream ; 27 import java.net.JarURLConnection ; 28 import java.net.MalformedURLException ; 29 import java.net.URISyntaxException ; 30 import java.net.URL ; 31 import java.net.URLConnection ; 32 import java.util.ArrayList ; 33 import java.util.Collections ; 34 import java.util.Enumeration ; 35 import java.util.HashMap ; 36 import java.util.List ; 37 import java.util.Map ; 38 import java.util.jar.JarEntry ; 39 import java.util.jar.JarFile ; 40 41 import org.jboss.virtual.plugins.context.AbstractURLHandler; 42 import org.jboss.virtual.plugins.context.StructuredVirtualFileHandler; 43 import org.jboss.virtual.plugins.vfs.helpers.PathTokenizer; 44 import org.jboss.virtual.spi.VFSContext; 45 import org.jboss.virtual.spi.VirtualFileHandler; 46 47 54 public class AbstractJarHandler extends AbstractURLHandler 55 implements StructuredVirtualFileHandler 56 { 57 58 private static final long serialVersionUID = 1; 59 60 61 private transient JarFile jar; 62 63 64 private transient List <VirtualFileHandler> entries; 65 private transient Map <String , VirtualFileHandler> entryMap; 66 67 74 protected static String getEntryName(JarEntry entry) 75 { 76 if (entry == null) 77 throw new IllegalArgumentException ("Null entry"); 78 return entry.getName(); 79 } 80 81 91 protected AbstractJarHandler(VFSContext context, VirtualFileHandler parent, URL url, String name) throws IOException 92 { 93 super(context, parent, url, name); 94 } 95 96 101 public JarFile getJar() 102 { 103 return jar; 104 } 105 106 113 protected void initJarFile(JarFile jarFile) throws IOException 114 { 115 119 120 this.jar = jarFile; 121 122 Enumeration <JarEntry > enumeration = jar.entries(); 123 if (enumeration.hasMoreElements() == false) 124 { 125 entries = Collections.emptyList(); 126 entryMap = Collections.emptyMap(); 127 return; 128 } 129 130 Map <String , VirtualFileHandler> parentMap = new HashMap <String , VirtualFileHandler>(); 132 ArrayList <ArrayList <JarEntry >> levelMapList = new ArrayList <ArrayList <JarEntry >>(); 133 entries = new ArrayList <VirtualFileHandler>(); 134 entryMap = new HashMap <String , VirtualFileHandler>(); 135 boolean trace = log.isTraceEnabled(); 136 while (enumeration.hasMoreElements()) 137 { 138 JarEntry entry = enumeration.nextElement(); 139 String [] paths = entry.getName().split("/"); 140 int depth = paths.length; 141 if( depth >= levelMapList.size() ) 142 { 143 for(int n = levelMapList.size(); n <= depth; n ++) 144 levelMapList.add(new ArrayList <JarEntry >()); 145 } 146 ArrayList <JarEntry > levelMap = levelMapList.get(depth); 147 levelMap.add(entry); 148 if( trace ) 149 log.trace("added "+entry.getName()+" at depth "+depth); 150 } 151 int level = 0; 153 for(ArrayList <JarEntry > levels : levelMapList) 154 { 155 if( trace ) 156 log.trace("Level("+level++ +"): "+levels); 157 for(JarEntry entry : levels) 158 { 159 String name = entry.getName(); 160 int slash = entry.isDirectory() ? name.lastIndexOf('/', name.length()-2) : 161 name.lastIndexOf('/', name.length()-1); 162 VirtualFileHandler parent = this; 163 String entryName = name; 164 if( slash >= 0 ) 165 { 166 String parentName = name.substring(0, slash+1); 168 parent = parentMap.get(parentName); 169 if( parent == null ) 170 { 171 parent = buildParents(parentName, parentMap, entry); 173 } 174 } 175 int start = slash+1; 177 int end = entry.isDirectory() ? name.length()-1 : name.length(); 178 entryName = name.substring(start, end); 179 VirtualFileHandler handler = this.createVirtualFileHandler(parent, entry, entryName); 180 if( entry.isDirectory() ) 181 { 182 parentMap.put(name, handler); 183 if( trace ) 184 log.trace("Added parent: "+name); 185 } 186 if( parent == this ) 187 { 188 entries.add(handler); 190 entryMap.put(entryName, handler); 191 } 192 else if( parent instanceof JarEntryHandler ) 193 { 194 JarEntryHandler ehandler = (JarEntryHandler) parent; 196 ehandler.addChild(handler); 197 } 198 else if( parent instanceof SynthenticDirEntryHandler ) 199 { 200 SynthenticDirEntryHandler ehandler = (SynthenticDirEntryHandler) parent; 202 ehandler.addChild(handler); 203 } 204 } 205 } 206 } 207 208 217 protected VirtualFileHandler buildParents(String parentName, 218 Map <String , VirtualFileHandler> parentMap, JarEntry entry) 219 throws IOException 220 { 221 VirtualFileHandler parent = this; 222 String [] paths = PathTokenizer.getTokens(parentName); 223 StringBuilder pathName = new StringBuilder (); 224 for(String path : paths) 225 { 226 VirtualFileHandler next = null; 227 pathName.append(path); 228 pathName.append('/'); 229 try 230 { 231 next = parent.findChild(path); 232 } 233 catch (IOException e) 234 { 235 URL url = getURL(parent, path); 237 next = new SynthenticDirEntryHandler(getVFSContext(), parent, path, 238 entry.getTime(), url); 239 parentMap.put(pathName.toString(), next); 240 if( parent == this ) 241 { 242 entries.add(next); 244 entryMap.put(path, next); 245 } 246 else if( parent instanceof JarEntryHandler ) 247 { 248 JarEntryHandler ehandler = (JarEntryHandler) parent; 250 ehandler.addChild(next); 251 } 252 else if( parent instanceof SynthenticDirEntryHandler ) 253 { 254 SynthenticDirEntryHandler ehandler = (SynthenticDirEntryHandler) parent; 256 ehandler.addChild(next); 257 } 258 } 259 parent = next; 260 } 261 return parent; 262 } 263 264 protected URL getURL(VirtualFileHandler parent, String path) 265 throws MalformedURLException 266 { 267 StringBuilder buffer = new StringBuilder (); 268 try 269 { 270 buffer.append(parent.toURL()); 271 if (buffer.charAt(buffer.length()-1) != '/') 272 buffer.append('/'); 273 buffer.append(path); 274 } 275 catch(URISyntaxException e) 276 { 277 throw new MalformedURLException (e.getMessage()); 279 } 280 URL url = new URL (buffer.toString()); 281 return url; 282 } 283 284 protected void doClose() 285 { 286 296 } 297 298 public boolean isLeaf() 299 { 300 checkClosed(); 301 return false; 302 } 303 304 public List <VirtualFileHandler> getChildren(boolean ignoreErrors) throws IOException 305 { 306 checkClosed(); 307 return entries; 308 } 309 310 public VirtualFileHandler findChild(String path) throws IOException 311 { 312 return super.structuredFindChild(path); 313 } 314 315 public VirtualFileHandler createChildHandler(String name) throws IOException 316 { 317 VirtualFileHandler child = entryMap.get(name); 318 if( child == null ) 319 throw new FileNotFoundException (this+" has no child: "+name); 320 return child; 321 } 322 323 332 protected VirtualFileHandler createVirtualFileHandler(VirtualFileHandler parent, JarEntry entry, 333 String entryName) 334 throws IOException 335 { 336 if (parent == null) 337 throw new IllegalArgumentException ("Null parent"); 338 if (entry == null) 339 throw new IllegalArgumentException ("Null entry"); 340 341 URL url = getURL(parent, entryName); 344 345 VFSContext context = parent.getVFSContext(); 346 347 VirtualFileHandler vfh; 348 if (JarUtils.isArchive(entry.getName())) 349 { 350 String flag = context.getOptions().get("useNoCopyJarHandler"); 351 boolean useNoCopyJarHandler = Boolean.valueOf(flag); 352 353 if( useNoCopyJarHandler ) 354 vfh = new NoCopyNestedJarHandler(context, parent, jar, entry, url); 355 else 356 vfh = new NestedJarHandler(context, parent, jar, entry, url, entryName); 357 } 358 else 359 { 360 if (entry.isDirectory()) 362 url = new URL (url.toString() + "/"); 363 vfh = new JarEntryHandler(context, parent, jar, entry, entryName, url); 364 } 365 366 return vfh; 367 } 368 369 376 private void readObject(ObjectInputStream in) 377 throws IOException , ClassNotFoundException 378 { 379 in.defaultReadObject(); 380 URL jarURL = super.getURL(); 382 URLConnection conn = jarURL.openConnection(); 383 if( conn instanceof JarURLConnection ) 384 { 385 JarURLConnection jconn = (JarURLConnection ) conn; 386 jar = jconn.getJarFile(); 387 } 389 else 390 { 391 throw new IOException ("Cannot restore from non-JarURLConnection, url: "+jarURL); 392 } 393 } 394 395 } 396 | Popular Tags |