⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 groovyclassloader.java

📁 大名鼎鼎的java动态脚本语言。已经通过了sun的认证
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
     * @return true if the class should be compiled again     */    protected boolean isRecompilable(Class cls) {        if (cls==null) return true;        if (recompile==null && !config.getRecompileGroovySource()) return false;        if (recompile!=null && !recompile.booleanValue()) return false;        if (!GroovyObject.class.isAssignableFrom(cls)) return false;        long timestamp = getTimeStamp(cls);         if (timestamp == Long.MAX_VALUE) return false;                return true;    }        /**     * sets if the recompilation should be enable. There are 3 possible     * values for this. Any value different than null overrides the     * value from the compiler configuration. true means to recompile if needed     * false means to never recompile.       * @param mode the recompilation mode     * @see CompilerConfiguration     */    public void setShouldRecompile(Boolean mode){        recompile = mode;    }            /**     * gets the currently set recompilation mode. null means, the      * compiler configuration is used. False means no recompilation and      * true means that recompilation will be done if needed.      * @return the recompilation mode     */    public Boolean isShouldRecompile(){        return recompile;    }    /**     * loads a class from a file or a parent classloader.     *     * @param name                      of the class to be loaded     * @param lookupScriptFiles         if false no lookup at files is done at all     * @param preferClassOverScript     if true the file lookup is only done if there is no class     * @param resolve                   @see ClassLoader#loadClass(java.lang.String, boolean)     * @return                          the class found or the class created from a file lookup     * @throws ClassNotFoundException     */    public Class loadClass(final String name, boolean lookupScriptFiles, boolean preferClassOverScript, boolean resolve)        throws ClassNotFoundException, CompilationFailedException    {        // look into cache        Class cls=getClassCacheEntry(name);                // enable recompilation?        boolean recompile = isRecompilable(cls);        if (!recompile) return cls;        // check security manager        SecurityManager sm = System.getSecurityManager();        if (sm != null) {            String className = name.replace('/', '.');            int i = className.lastIndexOf('.');            if (i != -1) {                sm.checkPackageAccess(className.substring(0, i));            }        }        // try parent loader        ClassNotFoundException last = null;        try {            Class parentClassLoaderClass = super.loadClass(name, resolve);            // always return if the parent loader was successfull             if (cls!=parentClassLoaderClass) return parentClassLoaderClass;        } catch (ClassNotFoundException cnfe) {            last = cnfe;        } catch (NoClassDefFoundError ncdfe) {            if (ncdfe.getMessage().indexOf("wrong name")>0) {                last = new ClassNotFoundException(name);            } else {                throw ncdfe;            }        }        if (cls!=null) {            // prefer class if no recompilation            preferClassOverScript |= !recompile;            if (preferClassOverScript) return cls;        }        // at this point the loading from a parent loader failed        // and we want to recompile if needed.        if (lookupScriptFiles) {            // synchronize on cache, as we want only one compilation            // at the same time            synchronized (classCache) {                // try groovy file                try {                    // check if recompilation already happend.                    if (getClassCacheEntry(name)!=cls) return getClassCacheEntry(name);                    URL source = resourceLoader.loadGroovySource(name);                    cls = recompile(source,name,cls);                } catch (IOException ioe) {                    last = new ClassNotFoundException("IOException while openening groovy source: " + name, ioe);                } finally {                    if (cls==null) {                        removeClassCacheEntry(name);                    } else {                        setClassCacheEntry(cls);                    }                }            }        }        if (cls==null) {            // no class found, there has to be an exception before then            if (last==null) throw new AssertionError(true);            throw last;        }        return cls;    }    /**     * (Re)Comipiles the given source.      * This method starts the compilation of a given source, if     * the source has changed since the class was created. For     * this isSourceNewer is called.     *      * @see #isSourceNewer(URL, Class)     * @param source the source pointer for the compilation     * @param className the name of the class to be generated     * @param oldClass a possible former class     * @return the old class if the source wasn't new enough, the new class else     * @throws CompilationFailedException if the compilation failed     * @throws IOException if the source is not readable     *      */    protected Class recompile(URL source, String className, Class oldClass) throws CompilationFailedException, IOException {        if (source != null) {            // found a source, compile it if newer            if ((oldClass!=null && isSourceNewer(source, oldClass)) || (oldClass==null)) {                sourceCache.remove(className);                return parseClass(source.openStream(),className);            }        }        return oldClass;    }    /**     * Implemented here to check package access prior to returning an     * already loaded class.     * @throws CompilationFailedException if the compilation failed     * @throws ClassNotFoundException if the class was not found     * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)     */    protected Class loadClass(final String name, boolean resolve) throws ClassNotFoundException {        return loadClass(name,true,false,resolve);    }    /**     * gets the time stamp of a given class. For groovy     * generated classes this usually means to return the value     * of the static field __timeStamp. If the parameter doesn't     * have such a field, then Long.MAX_VALUE is returned     *      * @param cls the class      * @return the time stamp     */    protected long getTimeStamp(Class cls) {        Long o;        try {            Field field = cls.getField(Verifier.__TIMESTAMP);            o = (Long) field.get(null);        } catch (Exception e) {            return Long.MAX_VALUE;        }        return o.longValue();    }    private URL getSourceFile(String name) {        String filename = name.replace('.', '/') + config.getDefaultScriptExtension();        URL ret = getResource(filename);        if (ret!=null && ret.getProtocol().equals("file")) {            String fileWithoutPackage = filename;            if (fileWithoutPackage.indexOf('/')!=-1){                int index = fileWithoutPackage.lastIndexOf('/');                fileWithoutPackage = fileWithoutPackage.substring(index+1);            }            File path = new File(ret.getFile()).getParentFile();            if (path.exists() && path.isDirectory()) {                File file = new File(path, fileWithoutPackage);                if (file.exists()) {                    // file.exists() might be case insensitive. Let's do                    // case sensitive match for the filename                    File parent = file.getParentFile();                    String[] files = parent.list();                    for (int j = 0; j < files.length; j++) {                        if (files[j].equals(fileWithoutPackage)) return ret;                    }                }            }            //file does not exist!            return null;        }        return ret;    }    /**     * Decides if the given source is newer than a class.     *      * @see #getTimeStamp(Class)     * @param source the source we may want to compile     * @param cls the former class     * @return true if the source is newer, false else     * @throws IOException if it is not possible to open an     * connection for the given source     */    protected boolean isSourceNewer(URL source, Class cls) throws IOException {        long lastMod;        // Special handling for file:// protocol, as getLastModified() often reports        // incorrect results (-1)        if (source.getProtocol().equals("file")) {            // Coerce the file URL to a File            String path = source.getPath().replace('/', File.separatorChar).replace('|', ':');            File file = new File(path);            lastMod = file.lastModified();        }        else {            lastMod = source.openConnection().getLastModified();        }        long classTime = getTimeStamp(cls);        return classTime+config.getMinimumRecompilationIntervall() < lastMod;    }    /**     * adds a classpath to this classloader.       * @param path is a jar file or a directory.     * @see #addURL(URL)     */    public void addClasspath(final String path) {        AccessController.doPrivileged(new PrivilegedAction() {            public Object run() {                try {                    File f = new File(path);                    URL newURL = f.toURI().toURL();                    URL[] urls = getURLs();                    for (int i=0; i<urls.length; i++) {                        if (urls[i].equals(newURL)) return null;                    }                    addURL(newURL);                } catch (MalformedURLException e) {                    //TODO: fail through ?                }                return null;            }        });    }    /**     * <p>Returns all Groovy classes loaded by this class loader.     *     * @return all classes loaded by this class loader     */    public Class[] getLoadedClasses() {        synchronized (classCache) {            return (Class[]) classCache.values().toArray(new Class[0]);        }    }        /**     * removes all classes from the class cache.     * @see #getClassCacheEntry(String)     * @see #setClassCacheEntry(Class)     * @see #removeClassCacheEntry(String)     */        public void clearCache() {        synchronized (classCache) {            classCache.clear();        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -