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]>

Reply via email to