You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/11/14 17:28:51 UTC

svn commit: r1541962 - in /tomcat/trunk/java/org/apache/jasper: JspC.java compiler/TldCache.java servlet/JasperInitializer.java

Author: markt
Date: Thu Nov 14 16:28:51 2013
New Revision: 1541962

URL: http://svn.apache.org/r1541962
Log:
Check the parsed TLD cache entries are not stale.

Modified:
    tomcat/trunk/java/org/apache/jasper/JspC.java
    tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java
    tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java

Modified: tomcat/trunk/java/org/apache/jasper/JspC.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/JspC.java?rev=1541962&r1=1541961&r2=1541962&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/JspC.java (original)
+++ tomcat/trunk/java/org/apache/jasper/JspC.java Thu Nov 14 16:28:51 2013
@@ -847,6 +847,10 @@ public class JspC extends Task implement
         org.apache.jasper.xmlparser.ParserUtils.validating=b;
     }
 
+    public boolean isValidateXml() {
+        return validateXml;
+    }
+
     public void setListErrors( boolean b ) {
         listErrors = b;
     }
@@ -1432,7 +1436,7 @@ public class JspC extends Task implement
         } catch (SAXException e) {
             throw new JasperException(e);
         }
-        tldCache = new TldCache(scanner.getUriTldResourcePathMap(),
+        tldCache = new TldCache(context, scanner.getUriTldResourcePathMap(),
                 scanner.getTldResourcePathTaglibXmlMap());
         context.setAttribute(TldCache.SERVLET_CONTEXT_ATTRIBUTE_NAME, tldCache);
         rctxt = new JspRuntimeContext(context, this);

Modified: tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java?rev=1541962&r1=1541961&r2=1541962&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/TldCache.java Thu Nov 14 16:28:51 2013
@@ -16,13 +16,22 @@
  */
 package org.apache.jasper.compiler;
 
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 
 import javax.servlet.ServletContext;
 
+import org.apache.jasper.JasperException;
+import org.apache.jasper.servlet.JasperInitializer;
 import org.apache.tomcat.util.descriptor.tld.TaglibXml;
+import org.apache.tomcat.util.descriptor.tld.TldParser;
 import org.apache.tomcat.util.descriptor.tld.TldResourcePath;
+import org.apache.tomcat.util.scan.Jar;
+import org.xml.sax.SAXException;
 
 /**
  * This class caches parsed instances of TLD files to remove the need for the
@@ -35,8 +44,11 @@ public class TldCache {
     public static final String SERVLET_CONTEXT_ATTRIBUTE_NAME =
             TldCache.class.getName();
 
-    private final Map<String, TldResourcePath> uriTldResourcePathMap = new HashMap<>();
-    private final Map<TldResourcePath, TaglibXml> tldResourcePathTaglibXmlMap = new HashMap<>();
+    private final ServletContext servletContext;
+    private final Map<String,TldResourcePath> uriTldResourcePathMap = new HashMap<>();
+    private final Map<TldResourcePath,TaglibXmlCacheEntry> tldResourcePathTaglibXmlMap =
+            new HashMap<>();
+    private final TldParser tldParser;
 
 
     public static TldCache getInstance(ServletContext servletContext) {
@@ -48,10 +60,21 @@ public class TldCache {
     }
 
 
-    public TldCache(Map<String, TldResourcePath> uriTldResourcePathMap,
+    public TldCache(ServletContext servletContext,
+            Map<String, TldResourcePath> uriTldResourcePathMap,
             Map<TldResourcePath, TaglibXml> tldResourcePathTaglibXmlMap) {
+        this.servletContext = servletContext;
         this.uriTldResourcePathMap.putAll(uriTldResourcePathMap);
-        this.tldResourcePathTaglibXmlMap.putAll(tldResourcePathTaglibXmlMap);
+        for (Entry<TldResourcePath, TaglibXml> entry : tldResourcePathTaglibXmlMap.entrySet()) {
+            TldResourcePath tldResourcePath = entry.getKey();
+            long lastModified[] = getLastModified(tldResourcePath);
+            TaglibXmlCacheEntry cacheEntry = new TaglibXmlCacheEntry(
+                    entry.getValue(), lastModified[0], lastModified[1]);
+            this.tldResourcePathTaglibXmlMap.put(tldResourcePath, cacheEntry);
+        }
+        boolean validate = Boolean.parseBoolean(
+                servletContext.getInitParameter(JasperInitializer.VALIDATE));
+        tldParser = new TldParser(true, validate);
     }
 
 
@@ -60,7 +83,83 @@ public class TldCache {
     }
 
 
-    public TaglibXml getTaglibXml(TldResourcePath tldResourcePath) {
-        return tldResourcePathTaglibXmlMap.get(tldResourcePath);
+    public TaglibXml getTaglibXml(TldResourcePath tldResourcePath) throws JasperException {
+        TaglibXmlCacheEntry cacheEntry = tldResourcePathTaglibXmlMap.get(tldResourcePath);
+        long lastModified[] = getLastModified(tldResourcePath);
+        if (lastModified[0] != cacheEntry.getWebAppPathLastModified() ||
+                lastModified[1] != cacheEntry.getEntryLastModified()) {
+            synchronized (cacheEntry) {
+                if (lastModified[0] != cacheEntry.getWebAppPathLastModified() ||
+                        lastModified[1] != cacheEntry.getEntryLastModified()) {
+                    // Re-parse TLD
+                    TaglibXml updatedTaglibXml;
+                    try {
+                        updatedTaglibXml = tldParser.parse(tldResourcePath);
+                    } catch (IOException | SAXException e) {
+                        throw new JasperException(e);
+                    }
+                    cacheEntry.setTaglibXml(updatedTaglibXml);
+                    cacheEntry.setWebAppPathLastModified(lastModified[0]);
+                    cacheEntry.setEntryLastModified(lastModified[1]);
+                }
+            }
+        }
+        return cacheEntry.getTaglibXml();
+    }
+
+
+    private long[] getLastModified(TldResourcePath tldResourcePath) {
+        long[] result = new long[2];
+        result[0] = -1;
+        result[1] = -1;
+        try {
+            URL url = servletContext.getResource(tldResourcePath.getWebappPath());
+            URLConnection conn = url.openConnection();
+            result[0] = conn.getLastModified();
+            Jar jar = tldResourcePath.getJar();
+            if (jar != null) {
+                result[1] = jar.getLastModified(tldResourcePath.getEntryName());
+            }
+        } catch (IOException e) {
+            // Ignore (shouldn't happen)
+        }
+        return result;
+    }
+
+    private static class TaglibXmlCacheEntry {
+        private volatile TaglibXml taglibXml;
+        private volatile long webAppPathLastModified;
+        private volatile long entryLastModified;
+
+        public TaglibXmlCacheEntry(TaglibXml taglibXml, long webAppPathLastModified,
+                long entryLastModified) {
+            this.taglibXml = taglibXml;
+            this.webAppPathLastModified = webAppPathLastModified;
+            this.entryLastModified = entryLastModified;
+        }
+
+        public TaglibXml getTaglibXml() {
+            return taglibXml;
+        }
+
+        public void setTaglibXml(TaglibXml taglibXml) {
+            this.taglibXml = taglibXml;
+        }
+
+        public long getWebAppPathLastModified() {
+            return webAppPathLastModified;
+        }
+
+        public void setWebAppPathLastModified(long webAppPathLastModified) {
+            this.webAppPathLastModified = webAppPathLastModified;
+        }
+
+        public long getEntryLastModified() {
+            return entryLastModified;
+        }
+
+        public void setEntryLastModified(long entryLastModified) {
+            this.entryLastModified = entryLastModified;
+        }
     }
 }

Modified: tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java?rev=1541962&r1=1541961&r2=1541962&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java (original)
+++ tomcat/trunk/java/org/apache/jasper/servlet/JasperInitializer.java Thu Nov 14 16:28:51 2013
@@ -63,7 +63,7 @@ public class JasperInitializer implement
         }
 
         context.setAttribute(TldCache.SERVLET_CONTEXT_ATTRIBUTE_NAME,
-                new TldCache(scanner.getUriTldResourcePathMap(),
+                new TldCache(context, scanner.getUriTldResourcePathMap(),
                         scanner.getTldResourcePathTaglibXmlMap()));
     }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org