Sync the TLD file scanning code for WEB-INF between Catalina and Jasper
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 20 Jul 2009 14:39:17 +0000 (14:39 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 20 Jul 2009 14:39:17 +0000 (14:39 +0000)
- Based on the Jasper algorithm
- Uses additional checks from Catalina (Jasper now ignores TLD files in WEB-INF/lib and WEB-INF classes)
- Adds comments noting the need to keep the two implementations in sync

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@795860 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/startup/TldConfig.java
java/org/apache/jasper/compiler/TldLocationsCache.java

index c5fc9cc..6713bf2 100644 (file)
@@ -29,6 +29,7 @@ import java.net.URLClassLoader;
 import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.jar.JarEntry;
@@ -38,6 +39,7 @@ import javax.naming.NameClassPair;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.DirContext;
+import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 
 import org.apache.catalina.Context;
@@ -331,7 +333,7 @@ public final class TldConfig  implements LifecycleListener {
         tldScanWebXml();
         
         // Stage 3a - TLDs under WEB-INF (not lib or classes)
-        tldScanResourcePaths(context.getResources(), WEB_INF);
+        tldScanResourcePaths(WEB_INF);
 
         // Stage 3b - .jar files in WEB-INF/lib/
         tldScanWebInfLib();
@@ -399,51 +401,51 @@ public final class TldConfig  implements LifecycleListener {
     }
     
     /*
-     * Scans the web application's subdirectory identified by rootPath,
-     * along with its subdirectories, for TLDs.
+     * Scans the web application's sub-directory identified by rootPath,
+     * along with its sub-directories, for TLDs.
      *
      * Initially, rootPath equals /WEB-INF/. The /WEB-INF/classes and
-     * /WEB-INF/lib subdirectories are excluded from the search, as per the
+     * /WEB-INF/lib sub-directories 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
+     * @param startPath The path whose sub-directories are to be searched for
      * TLDs
+     * 
+     * Keep code in sync with o.a.j.compiler.TldLocationsCache
      */
-    private void tldScanResourcePaths(DirContext resources,
-                                            String rootPath) {
+    private void tldScanResourcePaths(String startPath) {
 
         if (log.isTraceEnabled()) {
-            log.trace(sm.getString("tldConfig.webinfScan", rootPath));
+            log.trace(sm.getString("tldConfig.webinfScan", startPath));
         }
 
-        try {
-            NamingEnumeration<NameClassPair> items = resources.list(rootPath);
-            while (items.hasMoreElements()) {
-                NameClassPair item = items.nextElement();
-                String resourcePath = rootPath + item.getName();
-                if (!resourcePath.endsWith(TLD_EXT)
-                        && (resourcePath.equals("/WEB-INF/classes")
-                            || resourcePath.equals("/WEB-INF/lib"))) {
+        ServletContext ctxt = getContext().getServletContext();
+        
+        Set<String> dirList = ctxt.getResourcePaths(startPath);
+        if (dirList != null) {
+            Iterator<String> it = dirList.iterator();
+            while (it.hasNext()) {
+                String path = it.next();
+                if (!path.endsWith(TLD_EXT)
+                        && (path.startsWith("/WEB-INF/lib/")
+                                || path.startsWith("/WEB-INF/classes/"))) {
                     continue;
                 }
-                if (resourcePath.endsWith(TLD_EXT)) {
-                    if (resourcePath.startsWith("/WEB-INF/tags") &&
-                            !resourcePath.endsWith("implicit.tld")) {
+                if (path.endsWith(".tld")) {
+                    if (path.startsWith("/WEB-INF/tags/") &&
+                            !path.endsWith("implicit.tld")) {
                         continue;
                     }
                     try {
-                        tldScanTld(resourcePath);
+                        tldScanTld(path);
                     } catch (Exception e) {
                         log.warn(sm.getString(
-                                "tldConfig.webinfFail", resourcePath),e);
+                                "tldConfig.webinfFail", path),e);
                     }
                 } else {
-                    tldScanResourcePaths(resources, resourcePath + '/');
+                    tldScanResourcePaths(path);
                 }
             }
-        } catch (NamingException e) {
-            // Silent catch: it's valid that no /WEB-INF directory exists
         }
     }
     
index d01d59e..0dfd202 100644 (file)
@@ -245,7 +245,7 @@ public class TldLocationsCache {
         if (initialized) return;
         try {
             processWebDotXml();
-            processTldsInFileSystem("/WEB-INF/");
+            tldScanResourcePaths("/WEB-INF/");
             scanJars();
             initialized = true;
         } catch (Exception ex) {
@@ -416,8 +416,10 @@ public class TldLocationsCache {
      * Searches the filesystem under /WEB-INF for any TLD files, and adds
      * an implicit map entry to the taglib map for any TLD that has a <uri>
      * element.
+     * 
+     * Keep code in sync with o.a.c.startup.TldConfig
      */
-    private void processTldsInFileSystem(String startPath)
+    private void tldScanResourcePaths(String startPath)
             throws Exception {
 
         Set<String> dirList = ctxt.getResourcePaths(startPath);
@@ -425,30 +427,38 @@ public class TldLocationsCache {
             Iterator<String> it = dirList.iterator();
             while (it.hasNext()) {
                 String path = it.next();
-                if (path.endsWith("/")) {
-                    processTldsInFileSystem(path);
-                }
-                if (!path.endsWith(".tld")) {
+                if (!path.endsWith(".tld")
+                        && (path.startsWith("/WEB-INF/lib/")
+                                || path.startsWith("/WEB-INF/classes/"))) {
                     continue;
                 }
-                InputStream stream = ctxt.getResourceAsStream(path);
-                String uri = null;
-                try {
-                    uri = getUriFromTld(path, stream);
-                } finally {
-                    if (stream != null) {
-                        try {
-                            stream.close();
-                        } catch (Throwable t) {
-                            // do nothing
+                if (path.endsWith(".tld")) {
+                    if (path.startsWith("/WEB-INF/tags/") &&
+                            !path.endsWith("implicit.tld")) {
+                        continue;
+                    }
+                    InputStream stream = ctxt.getResourceAsStream(path);
+                    String uri = null;
+                    try {
+                        uri = getUriFromTld(path, stream);
+                    } finally {
+                        if (stream != null) {
+                            try {
+                                stream.close();
+                            } catch (Throwable t) {
+                                // do nothing
+                            }
                         }
                     }
+                    // Add implicit map entry only if its uri is not already
+                    // present in the map
+                    if (uri != null && mappings.get(uri) == null) {
+                        mappings.put(uri, new String[] { path, null });
+                    }
+                } else {
+                    tldScanResourcePaths(path);
                 }
-                // Add implicit map entry only if its uri is not already
-                // present in the map
-                if (uri != null && mappings.get(uri) == null) {
-                    mappings.put(uri, new String[] { path, null });
-                }
+
             }
         }
     }