Coverage Report - org.webslinger.commons.vfs.VFSClassLoader
 
Classes in this File Line Coverage Branch Coverage Complexity
VFSClassLoader
0%
0/99
0%
0/21
0
VFSClassLoader$1
0%
0/3
N/A
0
VFSClassLoader$FileAcceptor
N/A
N/A
0
 
 1  
 package org.webslinger.commons.vfs;
 2  
 
 3  
 import java.io.InputStream;
 4  
 import java.io.IOException;
 5  
 import java.net.URL;
 6  
 import java.security.CodeSource;
 7  
 import java.security.Permission;
 8  
 import java.security.PermissionCollection;
 9  
 import java.security.Permissions;
 10  
 import java.security.SecureClassLoader;
 11  
 import java.security.cert.Certificate;
 12  
 import java.util.Enumeration;
 13  
 import java.util.Iterator;
 14  
 import java.util.LinkedHashMap;
 15  
 import java.util.Map;
 16  
 import java.util.Vector;
 17  
 import java.util.jar.Attributes;
 18  
 
 19  
 import org.apache.commons.vfs.FileContent;
 20  
 import org.apache.commons.vfs.FileObject;
 21  
 import org.apache.commons.vfs.FileSystemException;
 22  
 import org.apache.commons.vfs.FileUtil;
 23  
 
 24  
 public class VFSClassLoader extends SecureClassLoader {
 25  0
     protected final Map<FileObject, FileObject> files = new LinkedHashMap<FileObject, FileObject>();
 26  
 
 27  
     public VFSClassLoader(ClassLoader parent, FileObject file) throws FileSystemException {
 28  0
         this(parent, new FileObject[] {file});
 29  0
     }
 30  
 
 31  
     public VFSClassLoader(ClassLoader parent, FileObject[] files) throws FileSystemException {
 32  0
         super(parent);
 33  0
         addFiles(files);
 34  0
     }
 35  
 
 36  
     protected FileObject createFileSystem(FileObject file) throws FileSystemException {
 37  0
         if (file.getType().hasChildren()) {
 38  0
             return file.getFileSystem().getFileSystemManager().createFileSystem(file);
 39  
         } else {
 40  0
             return file.getFileSystem().getFileSystemManager().createFileSystem("jar", file);
 41  
         }
 42  
     }
 43  
 
 44  
     public void addFiles(FileObject[] files) throws FileSystemException {
 45  0
         synchronized (this.files) {
 46  0
             for (FileObject file: files) {
 47  0
                 this.files.put(file, createFileSystem(file));
 48  
             }
 49  0
         }
 50  0
     }
 51  
 
 52  
     public void addFile(FileObject file) throws FileSystemException {
 53  0
         synchronized (files) {
 54  0
             files.put(file, createFileSystem(file));
 55  0
         }
 56  0
     }
 57  
 
 58  
     public void removeFile(FileObject file) throws FileSystemException {
 59  0
         synchronized (files) {
 60  0
             files.remove(file);
 61  0
         }
 62  0
     }
 63  
 
 64  
     protected FileObject findFile(String name) throws FileSystemException {
 65  0
         synchronized (files) {
 66  0
             for (FileObject root: files.values()) {
 67  0
                 FileObject file = root.resolveFile(name);
 68  0
                 if (file.exists()) return file;
 69  0
             }
 70  0
         }
 71  0
         return null;
 72  
     }
 73  
 
 74  
     protected void findFiles(String name, FileAcceptor acceptor) throws FileSystemException {
 75  0
         synchronized (files) {
 76  0
             for (FileObject root: files.values()) {
 77  0
                 FileObject file = root.resolveFile(name);
 78  0
                 if (file.exists() && acceptor.accept(file)) break;
 79  0
             }
 80  0
         }
 81  0
     }
 82  
 
 83  
     protected Class findClass(String name) throws ClassNotFoundException {
 84  0
         String fileName = name.replace('.', '/') + ".class";
 85  
         try {
 86  0
             FileObject file = findFile(fileName);
 87  0
             if (file == null) throw new ClassNotFoundException(name);
 88  0
             Certificate[] certs = file.getContent().getCertificates();
 89  0
             int pos = name.lastIndexOf('.');
 90  0
             String packageName = pos != -1 ? name.substring(0, pos) : null;
 91  0
             FileObject parent = file.getParent();
 92  0
             Package pkg = getPackage(packageName);
 93  0
             if (pkg != null) {
 94  0
                 if (pkg.isSealed()) {
 95  0
                     if (!pkg.isSealed(parent.getURL())) throw new ClassNotFoundException("redefine class in package that is sealed: " + name);
 96  0
                 } else if (isSealed(parent)) {
 97  0
                     throw new ClassNotFoundException("redefine sealed class in unsealed package: " + name);
 98  
                 }
 99  
             } else {
 100  0
                 definePackage(packageName, parent);
 101  
             }
 102  0
             CodeSource cs = new CodeSource(file.getFileSystem().getParentLayer().getURL(), certs);
 103  0
             byte[] bytes = FileUtil.getContent(file);
 104  0
             return defineClass(name, bytes, 0, bytes.length, cs);
 105  0
         } catch (IOException e) {
 106  0
             throw (ClassNotFoundException) new ClassNotFoundException(name).initCause(e);
 107  
         }
 108  
     }
 109  
 
 110  
     protected boolean isSealed(FileObject parent) throws FileSystemException {
 111  0
         return "true".equalsIgnoreCase((String) parent.getContent().getAttribute(Attributes.Name.SEALED.toString()));
 112  
     }
 113  
 
 114  
     protected Package definePackage(String packageName, FileObject parent) throws FileSystemException {
 115  0
         FileContent content = parent.getContent();
 116  
 
 117  0
         String specTitle = (String) content.getAttribute(Attributes.Name.SPECIFICATION_TITLE.toString());
 118  0
         String specVendor = (String) content.getAttribute(Attributes.Name.SPECIFICATION_VENDOR.toString());
 119  0
         String specVersion = (String) content.getAttribute(Attributes.Name.SPECIFICATION_VERSION.toString());
 120  0
         String implTitle = (String) content.getAttribute(Attributes.Name.IMPLEMENTATION_TITLE.toString());
 121  0
         String implVendor = (String) content.getAttribute(Attributes.Name.IMPLEMENTATION_VENDOR.toString());
 122  0
         String implVersion = (String) content.getAttribute(Attributes.Name.IMPLEMENTATION_VERSION.toString());
 123  
 
 124  0
         URL sealBase = isSealed(parent) ? parent.getURL() : null;
 125  
 
 126  0
         return definePackage(packageName, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, sealBase);
 127  
     }
 128  
 
 129  
     protected PermissionCollection getPermissions(CodeSource cs) {
 130  0
         String url = cs.getLocation().toString();
 131  0
         FileObject root = null;
 132  0
         synchronized (files) {
 133  0
             for (FileObject file: files.values()) {
 134  0
                 root = file;
 135  0
                 if (root.getName().getURI().equals(url)) break;
 136  0
                 root = null;
 137  
             }
 138  0
         }
 139  0
         if (root == null) return super.getPermissions(cs);
 140  
         try {
 141  0
             FileObject parent = root.getFileSystem().getParentLayer();
 142  0
             if (parent == null) return super.getPermissions(cs);
 143  
 
 144  0
             Permissions perms = new Permissions();
 145  0
             addPermissions(perms, super.getPermissions(cs));
 146  
 
 147  
             do {
 148  0
                 addPermissions(perms, super.getPermissions(new CodeSource(parent.getURL(), parent.getContent().getCertificates())));
 149  0
                 parent = parent.getFileSystem().getParentLayer();
 150  0
             } while (parent != null);
 151  
 
 152  0
             return perms;
 153  0
         } catch (FileSystemException e) {
 154  0
             throw (SecurityException) new SecurityException(e.getMessage()).initCause(e);
 155  
         }
 156  
     }
 157  
 
 158  
     protected void addPermissions(PermissionCollection target, PermissionCollection source) {
 159  0
         Enumeration<Permission> en = source.elements();
 160  0
         while (en.hasMoreElements()) {
 161  0
             target.add(en.nextElement());
 162  
         }
 163  0
     }
 164  
 
 165  
     protected URL findResource(String name) {
 166  
         try {
 167  0
             FileObject file = findFile(name);
 168  0
             return file != null ? file.getURL() : null;
 169  0
         } catch (FileSystemException e) {
 170  0
             throw (SecurityException) new SecurityException(e.getMessage()).initCause(e);
 171  
         }
 172  
     }
 173  
 
 174  
     protected Enumeration<URL> findResources(String name) throws IOException {
 175  0
         final Vector<URL> resources = new Vector<URL>();
 176  0
         findFiles(
 177  
             name,
 178  0
             new FileAcceptor() {
 179  
                 public boolean accept(FileObject file) throws FileSystemException {
 180  0
                     resources.add(file.getURL());
 181  0
                     return false;
 182  
                 }
 183  
             }
 184  
         );
 185  0
         return resources.elements();
 186  
     }
 187  
 
 188  
     public InputStream getResourceAsStream(String name) {
 189  
         try {
 190  0
             FileObject file = findFile(name);
 191  0
             return file != null ? file.getContent().getInputStream() : null;
 192  0
         } catch (FileSystemException e) {
 193  0
             return null;
 194  
         }
 195  
     }
 196  
 
 197  
     protected interface FileAcceptor {
 198  
         boolean accept(FileObject file) throws FileSystemException;
 199  
     }
 200  
 }