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

📄 repository.java

📁 精通tomcat书籍原代码,希望大家共同学习
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * Copyright 1999,2004 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package org.apache.tomcat.util.loader;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;


/**
 * A group of modules and libraries. 
 * 
 * Modules can have one or more jars and class dirs. Classloaders are created 
 * from modules when the module is started are be disposed when the module is stopped.
 * 
 * The module will delegate to the associated repository in addition to the 
 * normal delegation rules. The repository will search on all sibling modules.
 * This mechanism is defined in the MLetClassLoader and is also used by JBoss and
 * few other servers. 
 * 
 * TODO: explain more ( or point to the right jboss/mlet pages )
 * TODO: explain how this can be used for webapps to support better partitioning 
 *
 * @author Costin Manolache
 */
public class Repository {
   
    private static final boolean DEBUG=Loader.getProperty("loader.debug.Repository") != null;
    
    // Allows the (experimental) use of jar indexes
    // Right now ( for small set of jars, incomplete build ) it's a tiny 3.5 -> 3.4 sec dif.
    private static final boolean USE_IDX=Loader.getProperty("loader.Repository.noIndex") == null;
    
    private Vector loaders=new Vector();
    private String name;
    private Vector grpModules=new Vector();
    private transient Loader loader;
    
    private transient RepositoryClassLoader groupClassLoader;
    private Hashtable prefixes=new Hashtable();

    // For delegation
    private ClassLoader parentClassLoader;
    private Repository parent;


    private Repository() {
    }

    public Repository(Loader loader) {
        if( loader== null ) throw new NullPointerException();
        this.loader=loader;
    }

    public Loader getLoader() {
        return loader;
    }
    
    void addModule(  Module mod ) {
        mod.setRepository( this );

        grpModules.addElement(mod);
        if( loader.listener!=null ) {
            loader.listener.moduleAdd(mod);
        }
        
        if( parentClassLoader != null ) 
            mod.setParentClassLoader( parentClassLoader );

        if(! mod.isStarted()) {
            mod.start();
            //log("started " + mod);
        } else {
            //log("already started " + mod);
        }
        
        try {
            if( USE_IDX ) {
                processJarIndex(mod);
                // TODO: if we are in the initial starting, write cache only once
                // TODO: write it only if there is a change in the timestamp
                writeCacheIdx();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }
    
    public void newModule( String path ) {
        Module m=new Module();
        m.setPath( path );
        addModule( m );
    }
    
    public Enumeration getModules() {
        return grpModules.elements();
    }
    
    /** Reload any module that is modified
     */
    public void checkReload() {
        try {
        Enumeration mE=grpModules.elements();
        while( mE.hasMoreElements() ) {
            Module m=(Module)mE.nextElement();
            boolean modif=m.modified();
            log("Modified " + m + " " + modif);
            
            if( modif ) {
                m.stop();
                m.start();
            }
        }
        } catch( Throwable t ) {
            t.printStackTrace();
        }
    }

    /** Verify if any module is modified. This is a deep search, including dirs.
     *  Expensive operation.
     *  
     * @return
     */
    public boolean isModified() {
        try {
            Enumeration mE=grpModules.elements();
            while( mE.hasMoreElements() ) {
                Module m=(Module)mE.nextElement();
                boolean modif=m.modified();
                log("Modified " + m + " " + modif);
                if( modif ) return true;
            }
        } catch( Throwable t ) {
            t.printStackTrace();
        }
        return false;
    }
    
    Repository getParent() {
        return parent;
    }
    
    public String toString() {
        return "Repository " + name + "(" + getClasspathString() + ")";
    }

    private String getClasspathString() {
        StringBuffer sb=new StringBuffer();
        Enumeration mE=grpModules.elements();
        while( mE.hasMoreElements() ) {
            Module m=(Module)mE.nextElement();
            sb.append( m.getClasspathString() + ":");
        }
        return sb.toString();
    }

    /**
     * 
     * @param parent The parent group
     */
    public void setParent(Repository parent) {
        this.parent = parent;
    }
    
    /** Set the parent class loader - can be used instead of setParent, 
     * in case this is the top loader and needs to delagate to embedding app
     * 
     * @param myL
     */
    public void setParentClassLoader(ClassLoader myL) {
        this.parentClassLoader=myL;
    }


    /** Add a class loder to the group.
     *
     *  If this is a StandardClassLoader instance, it will be able to delegate
     * to the group.
     *
     *  If it's a regular ClassLoader - it'll be searched for classes, but
     * it will not be able to delegate to peers.
     *
     * In future we may fine tune this by using manifests.
     */
    void addClassLoader(ClassLoader cl ) {
        if( ( cl instanceof ModuleClassLoader )) {
            ((ModuleClassLoader)cl).setRepository(this);
        }
        loaders.addElement(cl);
        //    log("Adding classloader " + cl);
    }

    public String getName() {
        return name;
    }

    public void removeClassLoader(ClassLoader cl) {
        int oldSize=loaders.size();
        loaders.removeElement(cl);

        if(DEBUG) log("removed " + loaders.size() + "/" + oldSize + ": "  + cl);
        // TODO: remove from index
    }

    /** Return a class loader associated with the group.
     *  This will delegate to all modules in the group, then to parent.
     * 
     * @return
     */
    public ClassLoader getClassLoader() {
        if( groupClassLoader==null ) {
            
            ClassLoader pcl=parentClassLoader;
            if( pcl==null && parent!=null ) {
                pcl=parent.getClassLoader();
            } 
            if( pcl==null ) {
                pcl=Thread.currentThread().getContextClassLoader();

⌨️ 快捷键说明

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