1 16 package org.apache.commons.vfs.impl; 17 18 import org.apache.commons.vfs.FileObject; 19 import org.apache.commons.vfs.FileSystemException; 20 import org.apache.commons.vfs.FileSystemManager; 21 import org.apache.commons.vfs.FileType; 22 import org.apache.commons.vfs.NameScope; 23 24 import java.io.IOException ; 25 import java.net.URL ; 26 import java.security.CodeSource ; 27 import java.security.Permission ; 28 import java.security.PermissionCollection ; 29 import java.security.Permissions ; 30 import java.security.SecureClassLoader ; 31 import java.security.cert.Certificate ; 32 import java.util.ArrayList ; 33 import java.util.Enumeration ; 34 import java.util.Iterator ; 35 import java.util.jar.Attributes ; 36 import java.util.jar.Attributes.Name; 37 38 39 50 public class VFSClassLoader 51 extends SecureClassLoader 52 { 53 private final ArrayList resources = new ArrayList (); 54 55 62 public VFSClassLoader(final FileObject file, 63 final FileSystemManager manager) 64 throws FileSystemException 65 { 66 this(new FileObject[]{file}, manager, null); 67 } 68 69 77 public VFSClassLoader(final FileObject file, 78 final FileSystemManager manager, 79 final ClassLoader parent) 80 throws FileSystemException 81 { 82 this(new FileObject[]{file}, manager, parent); 83 } 84 85 93 public VFSClassLoader(final FileObject[] files, 94 final FileSystemManager manager) 95 throws FileSystemException 96 { 97 this(files, manager, null); 98 } 99 100 109 public VFSClassLoader(final FileObject[] files, 110 final FileSystemManager manager, 111 final ClassLoader parent) throws FileSystemException 112 { 113 super(parent); 114 addFileObjects(manager, files); 115 } 116 117 123 private void addFileObjects(final FileSystemManager manager, 124 final FileObject[] files) throws FileSystemException 125 { 126 for (int i = 0; i < files.length; i++) 127 { 128 FileObject file = files[i]; 129 if (!file.exists()) 130 { 131 continue; 133 } 134 135 if (manager.canCreateFileSystem(file)) 137 { 138 file = manager.createFileSystem(file); 140 } 141 142 resources.add(file); 143 } 144 } 145 146 152 protected Class findClass(final String name) throws ClassNotFoundException 153 { 154 try 155 { 156 final String path = name.replace('.', '/').concat(".class"); 157 final Resource res = loadResource(path); 158 if (res == null) 159 { 160 throw new ClassNotFoundException (name); 161 } 162 return defineClass(name, res); 163 } 164 catch (final IOException ioe) 165 { 166 throw new ClassNotFoundException (name, ioe); 167 } 168 } 169 170 173 private Class defineClass(final String name, final Resource res) 174 throws IOException 175 { 176 final URL url = res.getCodeSourceURL(); 177 final String pkgName = res.getPackageName(); 178 if (pkgName != null) 179 { 180 final Package pkg = getPackage(pkgName); 181 if (pkg != null) 182 { 183 if (pkg.isSealed()) 184 { 185 if (!pkg.isSealed(url)) 186 { 187 throw new FileSystemException("vfs.impl/pkg-sealed-other-url", pkgName); 188 } 189 } 190 else 191 { 192 if (isSealed(res)) 193 { 194 throw new FileSystemException("vfs.impl/pkg-sealing-unsealed", pkgName); 195 } 196 } 197 } 198 else 199 { 200 definePackage(pkgName, res); 201 } 202 } 203 204 final byte[] bytes = res.getBytes(); 205 final Certificate [] certs = 206 res.getFileObject().getContent().getCertificates(); 207 final CodeSource cs = new CodeSource (url, certs); 208 return defineClass(name, bytes, 0, bytes.length, cs); 209 } 210 211 214 private boolean isSealed(final Resource res) 215 throws FileSystemException 216 { 217 final String sealed = res.getPackageAttribute(Attributes.Name.SEALED); 218 return "true".equalsIgnoreCase(sealed); 219 } 220 221 224 private Package definePackage(final String name, 225 final Resource res) 226 throws FileSystemException 227 { 228 final String specTitle = res.getPackageAttribute(Name.SPECIFICATION_TITLE); 230 final String specVendor = res.getPackageAttribute(Attributes.Name.SPECIFICATION_VENDOR); 231 final String specVersion = res.getPackageAttribute(Name.SPECIFICATION_VERSION); 232 final String implTitle = res.getPackageAttribute(Name.IMPLEMENTATION_TITLE); 233 final String implVendor = res.getPackageAttribute(Name.IMPLEMENTATION_VENDOR); 234 final String implVersion = res.getPackageAttribute(Name.IMPLEMENTATION_VERSION); 235 236 final URL sealBase; 237 if (isSealed(res)) 238 { 239 sealBase = res.getCodeSourceURL(); 240 } 241 else 242 { 243 sealBase = null; 244 } 245 246 return definePackage(name, specTitle, specVersion, specVendor, 247 implTitle, implVersion, implVendor, sealBase); 248 } 249 250 254 protected PermissionCollection getPermissions(final CodeSource cs) 255 { 256 try 257 { 258 final String url = cs.getLocation().toString(); 259 FileObject file = lookupFileObject(url); 260 if (file == null) 261 { 262 return super.getPermissions(cs); 263 } 264 265 FileObject parentLayer = file.getFileSystem().getParentLayer(); 266 if (parentLayer == null) 267 { 268 return super.getPermissions(cs); 269 } 270 271 Permissions combi = new Permissions (); 272 PermissionCollection permCollect = super.getPermissions(cs); 273 copyPermissions(permCollect, combi); 274 275 for (FileObject parent = parentLayer; 276 parent != null; 277 parent = parent.getFileSystem().getParentLayer()) 278 { 279 final CodeSource parentcs = 280 new CodeSource (parent.getURL(), 281 parent.getContent().getCertificates()); 282 permCollect = super.getPermissions(parentcs); 283 copyPermissions(permCollect, combi); 284 } 285 286 return combi; 287 } 288 catch (final FileSystemException fse) 289 { 290 throw new SecurityException (fse.getMessage()); 291 } 292 } 293 294 297 protected void copyPermissions(final PermissionCollection src, 298 final PermissionCollection dest) 299 { 300 for (Enumeration elem = src.elements(); elem.hasMoreElements();) 301 { 302 final Permission permission = (Permission ) elem.nextElement(); 303 dest.add(permission); 304 } 305 } 306 307 311 private FileObject lookupFileObject(final String name) 312 { 313 final Iterator it = resources.iterator(); 314 while (it.hasNext()) 315 { 316 final FileObject object = (FileObject) it.next(); 317 if (name.equals(object.getName().getURI())) 318 { 319 return object; 320 } 321 } 322 return null; 323 } 324 325 329 protected URL findResource(final String name) 330 { 331 try 332 { 333 final Resource res = loadResource(name); 334 if (res != null) 335 { 336 return res.getURL(); 337 } 338 } 339 catch (final Exception mue) 340 { 341 } 344 345 return null; 346 } 347 348 353 protected Enumeration findResources(final String name) 354 { 355 return new Enumeration () 356 { 357 public boolean hasMoreElements() 358 { 359 return false; 360 } 361 362 public Object nextElement() 363 { 364 return null; 365 } 366 }; 367 } 368 369 373 private Resource loadResource(final String name) throws FileSystemException 374 { 375 final Iterator it = resources.iterator(); 376 while (it.hasNext()) 377 { 378 final FileObject baseFile = (FileObject) it.next(); 379 final FileObject file = 380 baseFile.resolveFile(name, NameScope.DESCENDENT_OR_SELF); 381 if (file.exists()) 382 { 383 return new Resource(name, baseFile, file); 384 } 385 } 386 387 return null; 388 } 389 } 390 | Popular Tags |