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

📄 dynamicrepositoryclassloader.java

📁 jsr170接口的java实现。是个apache的开源项目。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
     *     * @throws IllegalStateException if <code>this</code>     *      {@link DynamicRepositoryClassLoader} has already been destroyed     *      through the {@link #destroy()} method.     */    public DynamicRepositoryClassLoader reinstantiate(Session session, ClassLoader parent) {        log.debug("reinstantiate: Copying {} with parent {}", this, parent);        if (isDestroyed()) {            throw new IllegalStateException("Destroyed class loader cannot be recreated");        }        // create the new loader        DynamicRepositoryClassLoader newLoader =                new DynamicRepositoryClassLoader(session, this, parent);        // return the new loader        return newLoader;    }    //---------- URLClassLoader overwrites -------------------------------------    /**     * Reconfigures this class loader with the pattern list. That is the new     * pattern list completely replaces the current pattern list. This new     * pattern list will also be used later to configure the reinstantiated     * class loader.     * <p>     * If this class loader already has loaded classes using the old, replaced     * path list, it is set dirty.     * <p>     * If this class loader has already been destroyed, this method has no     * effect.     *     * @param classPath The list of path strings making up the (initial) class     *      path of this class loader. The strings may contain globbing     *      characters which will be resolved to build the actual class path.     */    public void reconfigure(String[] classPath) {        if (log.isDebugEnabled()) {            log.debug("reconfigure: Reconfiguring the with {}",                Arrays.asList(classPath));        }        // whether the loader is destroyed        if (isDestroyed()) {            log.warn("Cannot reconfigure this destroyed class loader");            return;        }        // deregister to old handles        ((DynamicPatternPath) getHandles()).removeListener(this);        // assign new handles and register        setHandles(new DynamicPatternPath(getSession(), classPath));        buildRepository();        ((DynamicPatternPath) getHandles()).addListener(this);        dirty = !hasLoadedResources();        log.debug("reconfigure: Class loader is dirty now: {}", (isDirty()                ? "yes"                : "no"));    }    //---------- RepositoryClassLoader overwrites -----------------------------    /**     * Calls the base class implementation to actually retrieve the resource.     * If the resource could be found and provides a non-<code>null</code>     * {@link ClassLoaderResource#getExpiryProperty() expiry property}, the     * resource is registered with an internal cache to check with when     * a repository modification is observed in {@link #onEvent(EventIterator)}.     *     * @param name The name of the resource to be found     *     * @return the {@link ClassLoaderResource} found for the name or     *      <code>null</code> if no such resource is available in the class     *      path.     *     * @throws NullPointerException If this class loader has already been     *      destroyed.     */    /* package */ ClassLoaderResource findClassLoaderResource(String name) {        // call the base class implementation to actually search for it        ClassLoaderResource res = super.findClassLoaderResource(name);        // if it could be found, we register it with the caches        if (res != null) {            // register the resource in the expiry map, if an appropriate            // property is available            Property prop = res.getExpiryProperty();            if (prop != null) {                try {                    modTimeCache.put(prop.getPath(), res);                } catch (RepositoryException re) {                    log.warn("Cannot register the resource " + res +                        " for expiry", re);                }            }        }        // and finally return the resource        return res;    }    /**     * Builds the repository list from the list of path patterns and appends     * the path entries from any added handles. This method may be used multiple     * times, each time replacing the currently defined repository list.     *     * @throws NullPointerException If this class loader has already been     *      destroyed.     */    protected synchronized void buildRepository() {        super.buildRepository();        // add added repositories        ClassPathEntry[] addedPath = getAddedRepositories();        if (addedPath != null && addedPath.length > 0) {            ClassPathEntry[] oldClassPath = getRepository();            ClassPathEntry[] newClassPath =                new ClassPathEntry[oldClassPath.length + addedPath.length];            System.arraycopy(oldClassPath, 0, newClassPath, 0,                oldClassPath.length);            System.arraycopy(addedPath, 0, newClassPath, oldClassPath.length,                addedPath.length);            setRepository(newClassPath);        }    }    //---------- ModificationListener interface -------------------------------    /**     * Handles a repository item modifcation events checking whether a class     * needs to be expired. As a side effect, this method sets the class loader     * dirty if a loaded class has been modified in the repository.     *     * @param events The iterator of repository events to be handled.     */    public void onEvent(EventIterator events) {        while (events.hasNext()) {            Event event = events.nextEvent();            String path;            try {                path = event.getPath();            } catch (RepositoryException re) {                log.warn("onEvent: Cannot get path of event, ignoring", re);                continue;            }                            log.debug(                "onEvent: Item {} has been modified, checking with cache", path);            ClassLoaderResource resource = (ClassLoaderResource) modTimeCache.get(path);            if (resource != null) {                log.debug("pageModified: Expiring cache entry {}", resource);                expireResource(resource);            } else {                // might be in not-found cache - remove from there                if (event.getType() == Event.NODE_ADDED                    || event.getType() == Event.PROPERTY_ADDED) {                    log.debug("pageModified: Clearing not-found cache for possible new class");                    cleanCache();                }            }        }    }    // ----------- PatternPath.Listener interface -------------------------    /**     * Handles modified matched path set by setting the class loader dirty.     * The internal class path is only rebuilt when the class loader is     * reinstantiated.     */    public void pathChanged() {        log.debug("handleListChanged: The path list has changed");        buildRepository();        dirty = true;    }    //----------- Object overwrite ---------------------------------------------    /**     * Returns a string representation of this class loader.     */    public String toString() {        if (isDestroyed()) {            return super.toString();        }        StringBuffer buf = new StringBuffer(super.toString());        buf.append(", dirty: ");        buf.append(isDirty());        return buf.toString();    }    //---------- internal ------------------------------------------------------    /**     * Sets the list of class path entries to add to the class path after     * reconfiguration or reinstantiation.     *     * @param addedRepositories The list of class path entries to keep for     *      readdition.     */    protected void setAddedRepositories(ClassPathEntry[] addedRepositories) {        this.addedRepositories = addedRepositories;    }    /**     * Returns the list of added class path entries to readd them to the class     * path after reconfiguring the class loader.     */    protected ClassPathEntry[] getAddedRepositories() {        return addedRepositories;    }    /**     * Adds the class path entry to the current class path list. If the class     * loader has already been destroyed, this method creates a single entry     * class path list with the new class path entry.     * <p>     * Besides adding the entry to the current class path, it is also added to     * the list to be readded after reconfiguration and/or reinstantiation.     *     * @see #getAddedRepositories()     * @see #setAddedRepositories(ClassPathEntry[])     */    protected void addClassPathEntry(ClassPathEntry cpe) {        super.addClassPathEntry(cpe);        // add the repsitory to the list of added repositories        ClassPathEntry[] oldClassPath = getAddedRepositories();        ClassPathEntry[] newClassPath = addClassPathEntry(oldClassPath, cpe);        setAddedRepositories(newClassPath);    }    /**     * Registers this class loader with the observation service to get     * information on page updates in the class path and to the path     * pattern list to get class path updates.     *     * @throws NullPointerException if this class loader has already been     *      destroyed.     */    private final void registerModificationListener() {        ((DynamicPatternPath) getHandles()).addListener(this);        log.debug("registerModificationListener: Registering to the observation service");        try {            ObservationManager om = getSession().getWorkspace().getObservationManager();            om.addEventListener(this, 255, "/", true, null, null, false);        } catch (RepositoryException re) {            log.error("registerModificationListener: Cannot register " +                this + " with observation manager", re);        }    }    /**     * Removes this instances registrations from the observation service and     * the path pattern list.     *     * @throws NullPointerException if this class loader has already been     *      destroyed.     */    private final void unregisterListener() {        ((DynamicPatternPath) getHandles()).removeListener(this);        log.debug("registerModificationListener: Deregistering from the observation service");        try {            ObservationManager om = getSession().getWorkspace().getObservationManager();            om.removeEventListener(this);        } catch (RepositoryException re) {            log.error("unregisterListener: Cannot unregister " +                this + " from observation manager", re);        }    }    /**     * Checks whether the page backing the resource has been updated with a     * version, such that this new version would be used to access the resource.     * In this case the resource has expired and the class loader needs to be     * set dirty.     *     * @param resource The <code>ClassLoaderResource</code> to check for     *      expiry.     */    private boolean expireResource(ClassLoaderResource resource) {        // check whether the resource is expired (only if a class has been loaded)        boolean exp = resource.getLoadedClass() != null && resource.isExpired();        // update dirty flag accordingly        dirty |= exp;        log.debug("expireResource: Loader dirty: {}", new Boolean(isDirty()));        // return the expiry status        return exp;    }    /**     * Returns the list of classpath entries after resetting each of them.     *     * @param list The list of {@link ClassPathEntry}s to reset     *     * @return The list of reset {@link ClassPathEntry}s.     */    private static ClassPathEntry[] resetClassPathEntries(            ClassPathEntry[] oldClassPath) {        if (oldClassPath != null) {            for (int i=0; i < oldClassPath.length; i++) {                ClassPathEntry entry = oldClassPath[i];                log.debug("resetClassPathEntries: Cloning {}", entry);                oldClassPath[i] = entry.copy();            }        } else {            log.debug("resetClassPathEntries: No list to reset");        }        return oldClassPath;    }}

⌨️ 快捷键说明

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