📄 repository.java
字号:
/*
* 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 + -