luehe 2002/12/16 13:23:25 Modified: jasper2/src/share/org/apache/jasper/compiler Tag: tomcat_4_branch TldLocationsCache.java Log: Fixed 14200: TLDs under WEB-INF are not scanned for URI mappings Revision Changes Path No revision No revision 1.4.2.1 +101 -73 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/TldLocationsCache.java Index: TldLocationsCache.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/TldLocationsCache.java,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -u -r1.4 -r1.4.2.1 --- TldLocationsCache.java 20 Jun 2002 23:00:43 -0000 1.4 +++ TldLocationsCache.java 16 Dec 2002 21:23:25 -0000 1.4.2.1 @@ -107,6 +107,7 @@ * the TLD of this tag library. * * @author Pierre Delisle + * @author Jan Luehe */ public class TldLocationsCache { @@ -118,45 +119,56 @@ public static final int ROOT_REL_URI = 1; public static final int NOROOT_REL_URI = 2; - static private final String WEB_XML = "/WEB-INF/web.xml"; + private static final String WEB_XML = "/WEB-INF/web.xml"; /** - * The mapping of the 'global' tag library URI to the location - * (resource path) of the TLD associated with that tag library. - * The location is returned as a String array: + * The mapping of the 'global' tag library URI to the location (resource + * path) of the TLD associated with that tag library. The location is + * returned as a String array: * [0] The location - * [1] If the location is a jar file, this is the location - * of the tld. + * [1] If the location is a jar file, this is the location of the tld. */ - private Hashtable mappings = new Hashtable(); + private Hashtable mappings; - private Hashtable tlds = new Hashtable(); + private Hashtable tlds; + + private boolean initialized; + private ServletContext ctxt; - private boolean initialized=false; - ServletContext ctxt; //********************************************************************* // Constructor and Initilizations + /** + * Constructor. + * + * @param ctxt the servlet context of the web application in which Jasper + * is running + */ public TldLocationsCache(ServletContext ctxt) { - this.ctxt=ctxt; + this.ctxt = ctxt; + mappings = new Hashtable(); + tlds = new Hashtable(); + initialized = false; } private void init() { if( initialized ) return; try { - processWebDotXml(ctxt); - processJars(ctxt); - initialized=true; + processWebDotXml(); + processJars(); + processTldsInFileSystem(); + initialized = true; } catch (JasperException ex) { Constants.message("jsp.error.internal.tldinit", new Object[] { ex.getMessage() }, Logger.ERROR); } } - - private void processWebDotXml(ServletContext ctxt) - throws JasperException - { + + /* + * Populates taglib map described in web.xml. + */ + private void processWebDotXml() throws JasperException { // Acquire an input stream to the web application deployment descriptor InputStream is = ctxt.getResourceAsStream(WEB_XML); @@ -168,11 +180,8 @@ } // Parse the web application deployment descriptor - ClassLoader cl = - // (ClassLoader) ctxt.getAttribute(Constants.SERVLET_CLASS_LOADER); - this.getClass().getClassLoader(); - ParserUtils pu = ParserUtils.createParserUtils(cl); - TreeNode webtld = pu.parseXMLDocument(WEB_XML, is); + TreeNode webtld = new ParserUtils().parseXMLDocument(WEB_XML, is); + Iterator taglibs = webtld.findChildren("taglib"); while (taglibs.hasNext()) { @@ -196,44 +205,38 @@ if (tagLoc.endsWith(".jar")) tagLoc2 = "META-INF/taglib.tld"; mappings.put(tagUri, new String[] {tagLoc, tagLoc2}); - } - } /** - * Process all the jar files contained in this web application + * Processes any JAR files contained in this web application's * WEB-INF/lib directory. */ - private void processJars(ServletContext ctxt) - throws JasperException - { - + private void processJars() throws JasperException { Set libSet = ctxt.getResourcePaths("/WEB-INF/lib"); if (libSet != null) { Iterator it = libSet.iterator(); while (it.hasNext()) { String resourcePath = (String) it.next(); if (resourcePath.endsWith(".jar")) - tldConfigJar(ctxt, resourcePath); + processTldsInJar(resourcePath); } } - } /** - * Process a TLD in the JAR file at the specified resource path - * (if there is one). Will update the URI mappings for all - * the .tld files found in the META-INF directory tree, if - * a <uri> element is defined in the TLD. + * Parses any TLD files located in the META-INF directory (or any + * subdirectory of it) of the JAR file at the given resource path, and adds + * an implicit map entry to the taglib map for any TLD that has a <uri> + * element. * * @param resourcePath Context-relative resource path */ - private void tldConfigJar(ServletContext ctxt, String resourcePath) - throws JasperException - { + private void processTldsInJar(String resourcePath) throws JasperException { + JarFile jarFile = null; InputStream stream = null; + try { URL url = ctxt.getResource(resourcePath); if (url == null) return; @@ -247,23 +250,15 @@ String name = entry.getName(); if (!name.startsWith("META-INF/")) continue; if (!name.endsWith(".tld")) continue; - //p("tldConfigJar(" + resourcePath + - // "): Processing entry '" + name + "'"); stream = jarFile.getInputStream(entry); - String uri = parseTldForUri(resourcePath, stream); - //p("uri in TLD is: " + uri); - if (uri != null) { - mappings.put(uri, - new String[]{resourcePath, name}); - //p("added mapping: " + uri + - // " -> " + resourcePath + " " + name); - } + String uri = getUriFromTld(resourcePath, stream); + // 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[]{ resourcePath, name }); + } } - // FIXME @@@ - // -- it seems that the JarURLConnection class caches JarFile - // objects for particular URLs, and there is no way to get - // it to release the cached entry, so - // there's no way to redeploy from the same JAR file. Wierd. + } catch (Exception ex) { if (stream != null) { try { @@ -275,24 +270,63 @@ jarFile.close(); } catch (Throwable t) {} } - } + throw new JasperException(ex); + } + } + + /* + * 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. + */ + private void processTldsInFileSystem() throws JasperException { + Set dirList = ctxt.getResourcePaths("/WEB-INF/"); + if (dirList != null) { + Iterator it = dirList.iterator(); + while (it.hasNext()) { + String path = (String) it.next(); + if (!path.endsWith(".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 }); + } + } + } } - private String parseTldForUri(String resourcePath, InputStream in) + /* + * Returns the value of the uri element of the given TLD, or null if the + * given TLD does not contain any such element. + */ + private String getUriFromTld(String resourcePath, InputStream in) throws JasperException { - // Parse the tag library descriptor at the specified resource path - ParserUtils pu = new ParserUtils(); - TreeNode tld = pu.parseXMLDocument(resourcePath, in); + TreeNode tld = new ParserUtils().parseXMLDocument(resourcePath, in); TreeNode uri = tld.findChild("uri"); if (uri != null) { String body = uri.getBody(); if (body != null) return body; } - return null; // No <uri> element is present + return null; } //********************************************************************* @@ -328,7 +362,7 @@ * ROOT_REL_URI * NOROOT_REL_URI */ - static public int uriType(String uri) { + public static int uriType(String uri) { if (uri.indexOf(':') != -1) { return ABS_URI; } else if (uri.startsWith("/")) { @@ -338,19 +372,13 @@ } } - public TagLibraryInfo getTagLibraryInfo( String uri ) { - if( ! initialized ) init(); - Object o=tlds.get( uri ); - if( o==null ) return null; - return (TagLibraryInfo)o; + public TagLibraryInfo getTagLibraryInfo(String uri) { + if (!initialized) init(); + return (TagLibraryInfo) tlds.get(uri); } - public void addTagLibraryInfo( String uri, TagLibraryInfo tld ) { - if( ! initialized ) init(); - tlds.put( uri, tld); - } - - private void p(String s) { - System.out.println("[TldLocationsCache] " + s); + public void addTagLibraryInfo(String uri, TagLibraryInfo tld) { + if (!initialized) init(); + tlds.put(uri, tld); } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>