📄 tldconfig.java
字号:
/*
* Returns the last modification date of the given sets of resources.
*
* @param resourcePaths
* @param jarPaths
*
* @return Last modification date
*/
private long getLastModified(Set resourcePaths, Map jarPaths)
throws Exception {
long lastModified = 0;
Iterator paths = resourcePaths.iterator();
while (paths.hasNext()) {
String path = (String) paths.next();
URL url = context.getServletContext().getResource(path);
if (url == null) {
log.debug( "Null url "+ path );
break;
}
long lastM = url.openConnection().getLastModified();
if (lastM > lastModified) lastModified = lastM;
if (log.isDebugEnabled()) {
log.debug( "Last modified " + path + " " + lastM);
}
}
if (jarPaths != null) {
paths = jarPaths.values().iterator();
while (paths.hasNext()) {
File jarFile = (File) paths.next();
long lastM = jarFile.lastModified();
if (lastM > lastModified) lastModified = lastM;
if (log.isDebugEnabled()) {
log.debug("Last modified " + jarFile.getAbsolutePath()
+ " " + lastM);
}
}
}
return lastModified;
}
private void processCache(File tldCache ) throws IOException {
// read the cache and return;
try {
FileInputStream in=new FileInputStream(tldCache);
ObjectInputStream ois=new ObjectInputStream( in );
String list[]=(String [])ois.readObject();
if( log.isDebugEnabled() )
log.debug("Reusing tldCache " + tldCache + " " + list.length);
for( int i=0; list!=null && i<list.length; i++ ) {
context.addApplicationListener(list[i]);
}
ois.close();
} catch( ClassNotFoundException ex ) {
ex.printStackTrace();
}
}
/**
* Create (if necessary) and return a Digester configured to process a tag
* library descriptor, looking for additional listener classes to be
* registered.
*/
private static Digester createTldDigester() {
return DigesterFactory.newDigester(xmlValidation,
xmlNamespaceAware,
new TldRuleSet());
}
/**
* Scan the JAR file at the specified resource path for TLDs in the
* <code>META-INF</code> subdirectory, and scan each TLD for application
* event listeners that need to be registered.
*
* @param resourcePath Resource path of the JAR file to scan
*
* @exception Exception if an exception occurs while scanning this JAR
*/
private void tldScanJar(String resourcePath) throws Exception {
if (log.isDebugEnabled()) {
log.debug(" Scanning JAR at resource path '" + resourcePath + "'");
}
URL url = context.getServletContext().getResource(resourcePath);
if (url == null) {
throw new IllegalArgumentException
(sm.getString("contextConfig.tldResourcePath",
resourcePath));
}
File file = new File(url.getFile());
file = file.getCanonicalFile();
tldScanJar(file);
}
/**
* Scans all TLD entries in the given JAR for application listeners.
*
* @param file JAR file whose TLD entries are scanned for application
* listeners
*/
private void tldScanJar(File file) throws Exception {
JarFile jarFile = null;
String name = null;
String jarPath = file.getAbsolutePath();
try {
jarFile = new JarFile(file);
Enumeration entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = (JarEntry) entries.nextElement();
name = entry.getName();
if (!name.startsWith("META-INF/")) {
continue;
}
if (!name.endsWith(".tld")) {
continue;
}
if (log.isTraceEnabled()) {
log.trace(" Processing TLD at '" + name + "'");
}
try {
tldScanStream(new InputSource(jarFile.getInputStream(entry)));
} catch (Exception e) {
log.error(sm.getString("contextConfig.tldEntryException",
name, jarPath, context.getPath()),
e);
}
}
} catch (Exception e) {
log.error(sm.getString("contextConfig.tldJarException",
jarPath, context.getPath()),
e);
} finally {
if (jarFile != null) {
try {
jarFile.close();
} catch (Throwable t) {
// Ignore
}
}
}
}
/**
* Scan the TLD contents in the specified input stream, and register
* any application event listeners found there. <b>NOTE</b> - It is
* the responsibility of the caller to close the InputStream after this
* method returns.
*
* @param resourceStream InputStream containing a tag library descriptor
*
* @exception Exception if an exception occurs while scanning this TLD
*/
private void tldScanStream(InputSource resourceStream)
throws Exception {
if (tldDigester == null){
tldDigester = createTldDigester();
}
synchronized (tldDigester) {
try {
tldDigester.push(this);
tldDigester.parse(resourceStream);
} finally {
tldDigester.push(null);
tldDigester.clear();
}
}
}
/**
* Scan the TLD contents at the specified resource path, and register
* any application event listeners found there.
*
* @param resourcePath Resource path being scanned
*
* @exception Exception if an exception occurs while scanning this TLD
*/
private void tldScanTld(String resourcePath) throws Exception {
if (log.isDebugEnabled()) {
log.debug(" Scanning TLD at resource path '" + resourcePath + "'");
}
InputSource inputSource = null;
try {
inputSource =
new InputSource(
context.getServletContext().getResourceAsStream(resourcePath));
if (inputSource == null) {
throw new IllegalArgumentException
(sm.getString("contextConfig.tldResourcePath",
resourcePath));
}
tldScanStream(inputSource);
} catch (Exception e) {
throw new ServletException
(sm.getString("contextConfig.tldFileException", resourcePath,
context.getPath()),
e);
}
}
/**
* Accumulate and return a Set of resource paths to be analyzed for
* tag library descriptors. Each element of the returned set will be
* the context-relative path to either a tag library descriptor file,
* or to a JAR file that may contain tag library descriptors in its
* <code>META-INF</code> subdirectory.
*
* @exception IOException if an input/output error occurs while
* accumulating the list of resource paths
*/
private Set tldScanResourcePaths() throws IOException {
if (log.isDebugEnabled()) {
log.debug(" Accumulating TLD resource paths");
}
Set resourcePaths = new HashSet();
// Accumulate resource paths explicitly listed in the web application
// deployment descriptor
if (log.isTraceEnabled()) {
log.trace(" Scanning <taglib> elements in web.xml");
}
String taglibs[] = context.findTaglibs();
for (int i = 0; i < taglibs.length; i++) {
String resourcePath = context.findTaglib(taglibs[i]);
// FIXME - Servlet 2.4 DTD implies that the location MUST be
// a context-relative path starting with '/'?
if (!resourcePath.startsWith("/")) {
resourcePath = "/WEB-INF/" + resourcePath;
}
if (log.isTraceEnabled()) {
log.trace(" Adding path '" + resourcePath +
"' for URI '" + taglibs[i] + "'");
}
resourcePaths.add(resourcePath);
}
DirContext resources = context.getResources();
if (resources != null) {
tldScanResourcePathsWebInf(resources, "/WEB-INF", resourcePaths);
}
// Return the completed set
return (resourcePaths);
}
/*
* Scans the web application's subdirectory identified by rootPath,
* along with its subdirectories, for TLDs.
*
* Initially, rootPath equals /WEB-INF. The /WEB-INF/classes and
* /WEB-INF/lib subdirectories are excluded from the search, as per the
* JSP 2.0 spec.
*
* @param resources The web application's resources
* @param rootPath The path whose subdirectories are to be searched for
* TLDs
* @param tldPaths The set of TLD resource paths to add to
*/
private void tldScanResourcePathsWebInf(DirContext resources,
String rootPath,
Set tldPaths)
throws IOException {
if (log.isTraceEnabled()) {
log.trace(" Scanning TLDs in " + rootPath + " subdirectory");
}
try {
NamingEnumeration items = resources.list(rootPath);
while (items.hasMoreElements()) {
NameClassPair item = (NameClassPair) items.nextElement();
String resourcePath = rootPath + "/" + item.getName();
if (!resourcePath.endsWith(".tld")
&& (resourcePath.startsWith("/WEB-INF/classes")
|| resourcePath.startsWith("/WEB-INF/lib"))) {
continue;
}
if (resourcePath.endsWith(".tld")) {
if (log.isTraceEnabled()) {
log.trace(" Adding path '" + resourcePath + "'");
}
tldPaths.add(resourcePath);
} else {
tldScanResourcePathsWebInf(resources, resourcePath,
tldPaths);
}
}
} catch (NamingException e) {
; // Silent catch: it's valid that no /WEB-INF directory exists
}
}
/**
* Returns a map of the paths to all JAR files that are accessible to the
* webapp and will be scanned for TLDs.
*
* The map always includes all the JARs under WEB-INF/lib, as well as
* shared JARs in the classloader delegation chain of the webapp's
* classloader.
*
* The latter constitutes a Tomcat-specific extension to the TLD search
* order defined in the JSP spec. It allows tag libraries packaged as JAR
* files to be shared by web applications by simply dropping them in a
* location that all web applications have access to (e.g.,
* <CATALINA_HOME>/common/lib).
*
* The set of shared JARs to be scanned for TLDs is narrowed down by
* the <tt>noTldJars</tt> class variable, which contains the names of JARs
* that are known not to contain any TLDs.
*
* @return Map of JAR file paths
*/
private Map getJarPaths() {
HashMap jarPathMap = null;
ClassLoader webappLoader = Thread.currentThread().getContextClassLoader();
ClassLoader loader = webappLoader;
while (loader != null) {
if (loader instanceof URLClassLoader) {
URL[] urls = ((URLClassLoader) loader).getURLs();
for (int i=0; i<urls.length; i++) {
// Expect file URLs
// This is definitely not as clean as using JAR URLs either
// over file or the custom jndi handler, but a lot less
// buggy overall
File file = new File(urls[i].getFile());
try {
file = file.getCanonicalFile();
} catch (IOException e) {
// Ignore
}
if (!file.exists()) {
continue;
}
String path = file.getAbsolutePath();
if (!path.endsWith(".jar")) {
continue;
}
/*
* Scan all JARs from WEB-INF/lib, plus any shared JARs
* that are not known not to contain any TLDs
*/
if (loader == webappLoader
|| noTldJars == null
|| !noTldJars.contains(file.getName())) {
if (jarPathMap == null) {
jarPathMap = new HashMap();
jarPathMap.put(path, file);
} else if (!jarPathMap.containsKey(path)) {
jarPathMap.put(path, file);
}
}
}
}
loader = loader.getParent();
}
return jarPathMap;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -