001    package org.shiftone.jrat.util;
002    
003    
004    import org.shiftone.jrat.util.io.IOUtil;
005    import org.shiftone.jrat.util.log.Logger;
006    import org.shiftone.jrat.util.regex.GlobMatcher;
007    
008    import java.io.ByteArrayOutputStream;
009    import java.io.File;
010    import java.io.IOException;
011    import java.io.InputStream;
012    import java.net.MalformedURLException;
013    import java.net.URL;
014    import java.net.URLClassLoader;
015    
016    
017    /**
018     * Class GlobClassLoader
019     *
020     * @author jeff@shiftone.org (Jeff Drost)
021     */
022    public class GlobClassLoader extends URLClassLoader {
023    
024        private static final Logger LOG = Logger.getLogger(GlobClassLoader.class);
025        private ClassLoader parent = null;
026        private GlobMatcher globMatcher = null;
027    
028        public GlobClassLoader(URL[] urls, String globPattern, ClassLoader parent) {
029    
030            super(urls, parent);
031    
032            this.parent = parent;
033            this.globMatcher = new GlobMatcher(globPattern);
034        }
035    
036    
037        public GlobClassLoader(File file, String globPattern, ClassLoader parent) throws MalformedURLException {
038            this(new URL[]{file.toURL()}, globPattern, parent);
039        }
040    
041    
042        public GlobClassLoader(URL[] urls, String globPattern) {
043    
044            super(urls);
045    
046            globMatcher = new GlobMatcher(globPattern);
047        }
048    
049    
050        protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
051    
052            Class klass = null;
053    
054            if (globMatcher.isMatch(name)) {
055                klass = loadClassHere(name);
056            } else {
057                klass = super.loadClass(name, resolve);
058            }
059    
060            return klass;
061        }
062    
063    
064        private Class loadClassHere(String name) throws ClassNotFoundException {
065    
066            Class klass = null;
067            String resourceName = null;
068            byte[] bytes = null;
069    
070            LOG.debug("loadClassHere(" + name + ")");
071    
072            try {
073                resourceName = name.replace('.', '/').concat(".class");
074                bytes = loadClassData(resourceName);
075                klass = defineClass(name, bytes, 0, bytes.length);
076            }
077            catch (Exception e) {
078                throw new ClassNotFoundException("not found :" + name, e);
079            }
080    
081            return klass;
082        }
083    
084    
085        private byte[] loadClassData(String resourceName) throws IOException {
086    
087            ClassLoader loader = null;
088            ByteArrayOutputStream out = null;
089            InputStream in = null;
090    
091            in = getResourceAsStream(resourceName);
092    
093            if (in == null) {
094                throw new IOException("class resource not found : " + resourceName);
095            }
096    
097            out = new ByteArrayOutputStream();
098    
099            IOUtil.copy(in, out);
100    
101            return out.toByteArray();
102        }
103    }