You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/07/06 08:18:58 UTC

[07/17] incubator-freemarker git commit: FREEMARKER-55: code cleanup in TaglibFactory, using generics and some formatting

FREEMARKER-55: code cleanup in TaglibFactory, using generics and some formatting


Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/196158b0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/196158b0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/196158b0

Branch: refs/heads/3
Commit: 196158b03c18534466d8a0275052515317475474
Parents: 8621226
Author: Woonsan Ko <wo...@apache.org>
Authored: Wed Jul 5 17:52:05 2017 -0400
Committer: Woonsan Ko <wo...@apache.org>
Committed: Wed Jul 5 17:52:05 2017 -0400

----------------------------------------------------------------------
 .../freemarker/servlet/jsp/TaglibFactory.java   | 323 +++++++++++--------
 1 file changed, 185 insertions(+), 138 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/196158b0/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
----------------------------------------------------------------------
diff --git a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
index 0ad9a49..e1df54f 100644
--- a/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
+++ b/freemarker-servlet/src/main/java/org/apache/freemarker/servlet/jsp/TaglibFactory.java
@@ -43,7 +43,6 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -100,14 +99,14 @@ public class TaglibFactory implements TemplateHashModel {
     /**
      * The default of {@link #getClasspathTlds()}; an empty list.
      */
-    public static final List DEFAULT_CLASSPATH_TLDS = Collections.EMPTY_LIST;
-    
+    public static final List<String> DEFAULT_CLASSPATH_TLDS = Collections.emptyList();
+
     /**
      * The default of {@link #getMetaInfTldSources()}; a list that contains
      * {@link WebInfPerLibJarMetaInfTldSource#INSTANCE}, which gives the behavior described in the JSP 2.2
      * specification.
      */
-    public static final List/*<? extends MetaInfTldSource>*/ DEFAULT_META_INF_TLD_SOURCES
+    public static final List<? extends MetaInfTldSource> DEFAULT_META_INF_TLD_SOURCES
             = Collections.singletonList(WebInfPerLibJarMetaInfTldSource.INSTANCE);
 
     private static final Logger LOG = LoggerFactory.getLogger(TaglibFactory.class);
@@ -124,17 +123,17 @@ public class TaglibFactory implements TemplateHashModel {
     private final ServletContext servletContext;
 
     private ObjectWrapper objectWrapper;
-    private List/*<MetaInfTldSource>*/ metaInfTldSources = DEFAULT_META_INF_TLD_SOURCES;
-    private List/*<String>*/ classpathTlds = DEFAULT_CLASSPATH_TLDS;
-    
+    private List<? extends MetaInfTldSource> metaInfTldSources = DEFAULT_META_INF_TLD_SOURCES;
+    private List<String> classpathTlds = DEFAULT_CLASSPATH_TLDS;
+
     boolean test_emulateNoUrlToFileConversions = false;
     boolean test_emulateNoJarURLConnections = false;
     boolean test_emulateJarEntryUrlOpenStreamFails = false;    
 
     private final Object lock = new Object(); 
-    private final Map taglibs = new HashMap();
-    private final Map tldLocations = new HashMap();
-    private List/*<String>*/ failedTldLocations = new ArrayList();
+    private final Map<String, Taglib> taglibs = new HashMap<>();
+    private final Map<String, TldLocation> tldLocations = new HashMap<>();
+    private List<String> failedTldLocations = new ArrayList<>();
     private int nextTldLocationLookupPhase = 0;
 
     public static MetaInfTldSource parseMetaInfTldLocation(String value) throws ParseException {
@@ -176,7 +175,7 @@ public class TaglibFactory implements TemplateHashModel {
                 final MetaInfTldSource metaInfTldSource = parseMetaInfTldLocation(value);
 
                 if (metaInfTldSources == null) {
-                    metaInfTldSources = new ArrayList();
+                    metaInfTldSources = new ArrayList<>();
                 }
 
                 metaInfTldSources.add(metaInfTldSource);
@@ -240,24 +239,28 @@ public class TaglibFactory implements TemplateHashModel {
             boolean failedTldListAlreadyIncluded = false;
             final TldLocation tldLocation;
             final String normalizedTaglibUri;
+
             try {
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("Locating TLD for taglib URI " + _StringUtil.jQuoteNoXSS(taglibUri) + ".");
                 }
-                
+
                 TldLocation explicitlyMappedTldLocation = getExplicitlyMappedTldLocation(taglibUri);
+
                 if (explicitlyMappedTldLocation != null) {
                     tldLocation = explicitlyMappedTldLocation;
                     normalizedTaglibUri = taglibUri;
                 } else {
                     // Taglib URI must be directly the path (no mapping).
-                    
+
                     final int urlType;
+
                     try {
                         urlType = getUriType(taglibUri);
                     } catch (MalformedURLException e) {
                         throw new TaglibGettingException("Malformed taglib URI: " + _StringUtil.jQuote(taglibUri), e);
                     }
+
                     if (urlType == URL_TYPE_RELATIVE) {
                         normalizedTaglibUri = resolveRelativeUri(taglibUri);
                     } else if (urlType == URL_TYPE_ABSOLUTE) {
@@ -326,13 +329,16 @@ public class TaglibFactory implements TemplateHashModel {
             if (failedTldLocations.isEmpty()) {
                 return null;
             }
+
             StringBuilder sb = new StringBuilder();
+
             for (int i = 0; i < failedTldLocations.size(); i++) {
                 if (i != 0) {
                     sb.append(", ");
                 }
                 sb.append(_StringUtil.jQuote(failedTldLocations.get(i)));
             }
+
             return sb.toString();
         }
     }
@@ -345,18 +351,11 @@ public class TaglibFactory implements TemplateHashModel {
         return false;
     }
 
-    private void checkNotStarted() {
-        synchronized (lock) {
-            if (nextTldLocationLookupPhase != 0) {
-                throw new IllegalStateException(TaglibFactory.class.getName() + " object was already in use.");
-            }
-        }
-    }
-
     private TldLocation getExplicitlyMappedTldLocation(final String uri) throws SAXException, IOException,
             TaglibGettingException {
         while (true) {
             final TldLocation tldLocation = (TldLocation) tldLocations.get(uri);
+
             if (tldLocation != null) {
                 return tldLocation;
             }
@@ -383,6 +382,7 @@ public class TaglibFactory implements TemplateHashModel {
             default:
                 throw new BugException();
             }
+
             nextTldLocationLookupPhase++;
         }
     }
@@ -392,10 +392,12 @@ public class TaglibFactory implements TemplateHashModel {
 
         WebXmlParser webXmlParser = new WebXmlParser();
         InputStream in = servletContext.getResourceAsStream("/WEB-INF/web.xml");
+
         if (in == null) {
             LOG.debug("No web.xml was found in servlet context");
             return;
         }
+
         try {
             parseXml(in, servletContext.getResource("/WEB-INF/web.xml").toExternalForm(), webXmlParser);
         } finally {
@@ -411,34 +413,32 @@ public class TaglibFactory implements TemplateHashModel {
 
     private void addTldLocationsFromServletContextResourceTlds(String basePath)
             throws IOException, SAXException {
-        Set unsortedResourcePaths = servletContext.getResourcePaths(basePath);
+        Set<String> unsortedResourcePaths = servletContext.getResourcePaths(basePath);
+
         if (unsortedResourcePaths != null) {
-            List/*<String>*/ resourcePaths = new ArrayList/*<String>*/(unsortedResourcePaths);
+            List<String> resourcePaths = new ArrayList<>(unsortedResourcePaths);
             Collections.sort(resourcePaths);
-            // First process the files...
-            for (Iterator it = resourcePaths.iterator(); it.hasNext(); ) {
-                String resourcePath = (String) it.next();
+
+            for (String resourcePath : resourcePaths) {
+                // First process the files...
                 if (resourcePath.endsWith(".tld")) {
                     addTldLocationFromTld(new ServletContextTldLocation(resourcePath));
                 }
-            }
-            // ... only later the directories
-            for (Iterator it = resourcePaths.iterator(); it.hasNext(); ) {
-                String resourcePath = (String) it.next();
-                if (resourcePath.endsWith("/")) {
+                // ... only later the directories
+                else if (resourcePath.endsWith("/")) {
                     addTldLocationsFromServletContextResourceTlds(resourcePath);
                 }
             }
         }
     }
-    
+
     private void addTldLocationsFromMetaInfTlds() throws IOException, SAXException {
         if (metaInfTldSources == null || metaInfTldSources.isEmpty()) {
             return;
         }
 
-        Set/*<URLWithExternalForm>*/ cpMetaInfDirUrlsWithEF = null;
-        
+        Set<URLWithExternalForm> cpMetaInfDirUrlsWithEF = null;
+
         // Skip past the last "clear":
         int srcIdxStart = 0;
         for (int i = metaInfTldSources.size() - 1; i >= 0; i--) {
@@ -447,30 +447,30 @@ public class TaglibFactory implements TemplateHashModel {
                 break;
             }
         }
-        
+
         for (int srcIdx = srcIdxStart; srcIdx < metaInfTldSources.size(); srcIdx++) {
             MetaInfTldSource miTldSource = (MetaInfTldSource) metaInfTldSources.get(srcIdx);
-            
+
             if (miTldSource == WebInfPerLibJarMetaInfTldSource.INSTANCE) {
                 addTldLocationsFromWebInfPerLibJarMetaInfTlds();
             } else if (miTldSource instanceof ClasspathMetaInfTldSource) {
                 ClasspathMetaInfTldSource cpMiTldLocation = (ClasspathMetaInfTldSource) miTldSource;
+
                 if (LOG.isDebugEnabled()) {
                     LOG.debug("Looking for TLD-s in "
                             + "classpathRoots[" + cpMiTldLocation.getRootContainerPattern() + "]"
                             + META_INF_ABS_PATH + "**/*.tld");
                 }
-                
+
                 if (cpMetaInfDirUrlsWithEF == null) {
                     cpMetaInfDirUrlsWithEF = collectMetaInfUrlsFromClassLoaders();
                 }
 
-                for (Iterator iterator = cpMetaInfDirUrlsWithEF.iterator(); iterator.hasNext(); ) {
-                    URLWithExternalForm urlWithEF = (URLWithExternalForm) iterator.next();
+                for (URLWithExternalForm urlWithEF : cpMetaInfDirUrlsWithEF) {
                     final URL url = urlWithEF.getUrl();
                     final boolean isJarUrl = isJarUrl(url);
                     final String urlEF = urlWithEF.externalForm;
-                    
+
                     final String rootContainerUrl;
                     if (isJarUrl) {
                         int sep = urlEF.indexOf(JAR_URL_ENTRY_PATH_START);
@@ -480,7 +480,7 @@ public class TaglibFactory implements TemplateHashModel {
                                 ? urlEF.substring(0, urlEF.length() - META_INF_REL_PATH.length())
                                 : urlEF;
                     }
-                    
+
                     if (cpMiTldLocation.getRootContainerPattern().matcher(rootContainerUrl).matches()) {
                         final File urlAsFile = urlToFileOrNull(url);
                         if (urlAsFile != null) {
@@ -502,10 +502,10 @@ public class TaglibFactory implements TemplateHashModel {
     private void addTldLocationsFromWebInfPerLibJarMetaInfTlds() throws IOException, SAXException {
         LOG.debug("Looking for TLD locations in servletContext:/WEB-INF/lib/*.{jar,zip}{}*.tld", META_INF_ABS_PATH);
 
-        Set libEntPaths = servletContext.getResourcePaths("/WEB-INF/lib");
+        Set<String> libEntPaths = servletContext.getResourcePaths("/WEB-INF/lib");
+
         if (libEntPaths != null) {
-            for (Iterator iter = libEntPaths.iterator(); iter.hasNext(); ) {
-                final String libEntryPath = (String) iter.next();
+            for (String libEntryPath : libEntPaths) {
                 if (isJarPath(libEntryPath)) {
                     addTldLocationsFromServletContextJar(libEntryPath);
                 }
@@ -517,24 +517,25 @@ public class TaglibFactory implements TemplateHashModel {
         if (classpathTlds == null || classpathTlds.size() == 0) {
             return;
         }
-        
+
         LOG.debug("Looking for TLD locations in TLD-s specified in cfg.classpathTlds");
-        
-        for (Iterator it = classpathTlds.iterator(); it.hasNext(); ) {
-            String tldResourcePath = (String) it.next();
+
+        for (String tldResourcePath : classpathTlds) {
             if (tldResourcePath.trim().length() == 0) {
                 throw new TaglibGettingException("classpathTlds can't contain empty item"); 
             }
-            
+
             if (!tldResourcePath.startsWith("/")) {
                 tldResourcePath = "/" + tldResourcePath;
             }
+
             if (tldResourcePath.endsWith("/")) {
                 throw new TaglibGettingException("classpathTlds can't specify a directory: " + tldResourcePath); 
             }
-            
+
             ClasspathTldLocation tldLocation = new ClasspathTldLocation(tldResourcePath);
             InputStream in;
+
             try {
                 in = tldLocation.getInputStream();
             } catch (IOException e) {
@@ -544,6 +545,7 @@ public class TaglibFactory implements TemplateHashModel {
                 }
                 in = null;
             }
+
             if (in != null) {
                 try {
                     addTldLocationFromTld(in, tldLocation);
@@ -561,15 +563,17 @@ public class TaglibFactory implements TemplateHashModel {
             final String jarResourcePath)
             throws IOException, MalformedURLException, SAXException {
         final String metaInfEntryPath = normalizeJarEntryPath(META_INF_ABS_PATH, true);
-        
+
         // Null for non-random-access backing resource:
         final JarFile jarFile = servletContextResourceToFileOrNull(jarResourcePath);
+
         if (jarFile != null) {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Scanning for " + META_INF_ABS_PATH + "*.tld-s in JarFile: servletContext:"
                         + jarResourcePath);
             }
-            for (Enumeration/*<JarEntry>*/ entries = jarFile.entries(); entries.hasMoreElements(); ) {
+
+            for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements(); ) {
                 final JarEntry curEntry = (JarEntry) entries.nextElement();
                 final String curEntryPath = normalizeJarEntryPath(curEntry.getName(), false);
                 if (curEntryPath.startsWith(metaInfEntryPath) && curEntryPath.endsWith(".tld")) {
@@ -586,13 +590,15 @@ public class TaglibFactory implements TemplateHashModel {
             if (in == null) {
                 throw new IOException("ServletContext resource not found: " + jarResourcePath);
             }
+
             try {
                 ZipInputStream zipIn = new ZipInputStream(in);
+
                 try {
                     while (true) {
                         ZipEntry curEntry = zipIn.getNextEntry();
                         if (curEntry == null) break;
-        
+
                         String curEntryPath = normalizeJarEntryPath(curEntry.getName(), false);
                         if (curEntryPath.startsWith(metaInfEntryPath) && curEntryPath.endsWith(".tld")) {
                             addTldLocationFromTld(zipIn,
@@ -625,38 +631,46 @@ public class TaglibFactory implements TemplateHashModel {
         // Null when URLConnection is used
         // (like "file:/C:/foo%20bar/baaz.jar" in "jar:file:/C:/foo%20bar/baaz.jar!/META-INF/"):
         final String rawJarContentUrlEF;
+
         {
             final URLConnection urlCon = jarBaseEntryUrl.openConnection();
+
             if (!test_emulateNoJarURLConnections && urlCon instanceof JarURLConnection) {
                 final JarURLConnection jarCon = (JarURLConnection) urlCon;
                 jarFile = jarCon.getJarFile();
                 rawJarContentUrlEF = null; // Not used as we have a JarURLConnection
                 baseEntryPath = normalizeJarEntryPath(jarCon.getEntryName(), true);
+
                 if (baseEntryPath == null) {
                     throw newFailedToExtractEntryPathException(jarBaseEntryUrl);
                 }
             } else {
                 final String jarBaseEntryUrlEF = jarBaseEntryUrl.toExternalForm();
                 final int jarEntrySepIdx = jarBaseEntryUrlEF.indexOf(JAR_URL_ENTRY_PATH_START);
+
                 if (jarEntrySepIdx == -1) {
                     throw newFailedToExtractEntryPathException(jarBaseEntryUrl);
                 }
+
                 rawJarContentUrlEF = jarBaseEntryUrlEF.substring(jarBaseEntryUrlEF.indexOf(':') + 1, jarEntrySepIdx);
                 baseEntryPath = normalizeJarEntryPath(
                         jarBaseEntryUrlEF.substring(jarEntrySepIdx + JAR_URL_ENTRY_PATH_START.length()), true);
-    
+
                 File rawJarContentAsFile = urlToFileOrNull(new URL(rawJarContentUrlEF));
                 jarFile = rawJarContentAsFile != null ? new JarFile(rawJarContentAsFile) : null;
             }
         }
+
         if (jarFile != null) {  // jarFile == null => fall back to streamed access
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Scanning for " + META_INF_ABS_PATH + "**/*.tld-s in random access mode: "
                         + jarBaseEntryUrl);
             }
-            for (Enumeration/*<JarEntry>*/ entries = jarFile.entries(); entries.hasMoreElements(); ) {
+
+            for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements(); ) {
                 final JarEntry curEntry = (JarEntry) entries.nextElement();
                 final String curEntryPath = normalizeJarEntryPath(curEntry.getName(), false);
+
                 if (curEntryPath.startsWith(baseEntryPath) && curEntryPath.endsWith(".tld")) {
                     final String curEntryBaseRelativePath = curEntryPath.substring(baseEntryPath.length());
                     final URL tldUrl = createJarEntryUrl(jarBaseEntryUrl, curEntryBaseRelativePath);
@@ -669,10 +683,12 @@ public class TaglibFactory implements TemplateHashModel {
                 LOG.debug("Scanning for " + META_INF_ABS_PATH + "**/*.tld-s in stream mode (slow): "
                         + rawJarContentUrlEF);
             }
-        
+
             final InputStream in = new URL(rawJarContentUrlEF).openStream();
+
             try {
                 ZipInputStream zipIn = new ZipInputStream(in);
+
                 try {
                     while (true) {
                         ZipEntry curEntry = zipIn.getNextEntry();
@@ -709,17 +725,18 @@ public class TaglibFactory implements TemplateHashModel {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Scanning for *.tld-s in File directory: " + _StringUtil.jQuoteNoXSS(dir));
             }
+
             File[] tldFiles = dir.listFiles(new FilenameFilter() {
-    
                 @Override
                 public boolean accept(File urlAsFile, String name) {
                     return isTldFileNameIgnoreCase(name);
                 }
-    
             });
+
             if (tldFiles == null) {
                 throw new IOException("Can't list this directory for some reason: " + dir);
             }
+
             for (final File file : tldFiles) {
                 addTldLocationFromTld(new FileTldLocation(file));
             }
@@ -727,12 +744,13 @@ public class TaglibFactory implements TemplateHashModel {
             LOG.warn("Skipped scanning for *.tld for non-existent directory: " + _StringUtil.jQuoteNoXSS(dir));
         }
     }
-    
+
     /**
      * Adds the TLD location mapping from the TLD itself.
      */
     private void addTldLocationFromTld(TldLocation tldLocation) throws IOException, SAXException {
         InputStream in = tldLocation.getInputStream();
+
         try {
             addTldLocationFromTld(in, tldLocation);
         } finally {
@@ -750,6 +768,7 @@ public class TaglibFactory implements TemplateHashModel {
     private void addTldLocationFromTld(InputStream reusedIn, TldLocation tldLocation) throws SAXException,
             IOException {
         String taglibUri;
+
         try {
             taglibUri = getTaglibUriFromTld(reusedIn, tldLocation.getXmlSystemId());
         } catch (SAXException e) {
@@ -759,8 +778,9 @@ public class TaglibFactory implements TemplateHashModel {
             }
             taglibUri = null;
         }
+
         if (taglibUri != null) {
-                addTldLocation(tldLocation, taglibUri);
+            addTldLocation(tldLocation, taglibUri);
         }
     }
 
@@ -772,6 +792,7 @@ public class TaglibFactory implements TemplateHashModel {
             }
         } else {
             tldLocations.put(taglibUri, tldLocation);
+
             if (LOG.isDebugEnabled()) {
                 LOG.debug("Mapped taglib URI " + _StringUtil.jQuoteNoXSS(taglibUri)
                         + " to TLD location " + _StringUtil.jQuoteNoXSS(tldLocation));
@@ -779,24 +800,27 @@ public class TaglibFactory implements TemplateHashModel {
         }
     }
 
-    private static Set/*<URLWithExternalForm>*/ collectMetaInfUrlsFromClassLoaders() throws IOException {
-        final Set/*<URLWithExternalForm>*/ metainfDirUrls = new TreeSet();
-    
+    private static Set<URLWithExternalForm> collectMetaInfUrlsFromClassLoaders() throws IOException {
+        final Set<URLWithExternalForm> metainfDirUrls = new TreeSet<>();
         final ClassLoader tccl = tryGetThreadContextClassLoader();
+
         if (tccl != null) {
             collectMetaInfUrlsFromClassLoader(tccl, metainfDirUrls);
         }
-    
+
         final ClassLoader cccl = TaglibFactory.class.getClassLoader();
+
         if (!isDescendantOfOrSameAs(tccl, cccl)) {
             collectMetaInfUrlsFromClassLoader(cccl, metainfDirUrls);
         }
+
         return metainfDirUrls;
     }
 
-    private static void collectMetaInfUrlsFromClassLoader(ClassLoader cl, Set/* <URLWithExternalForm> */metainfDirUrls)
+    private static void collectMetaInfUrlsFromClassLoader(ClassLoader cl, Set<URLWithExternalForm> metainfDirUrls)
             throws IOException {
-        Enumeration/*<URL>*/ urls = cl.getResources(META_INF_REL_PATH);
+        Enumeration<URL> urls = cl.getResources(META_INF_REL_PATH);
+
         if (urls != null) {
             while (urls.hasMoreElements()) {
                 metainfDirUrls.add(new URLWithExternalForm((URL) urls.nextElement()));
@@ -821,6 +845,7 @@ public class TaglibFactory implements TemplateHashModel {
             LOG.debug("Loading taglib for URI " + _StringUtil.jQuoteNoXSS(taglibUri)
                     + " from TLD location " + _StringUtil.jQuoteNoXSS(tldLocation));
         }
+
         final Taglib taglib = new Taglib(servletContext, tldLocation, objectWrapper);
         taglibs.put(taglibUri, taglib);
         tldLocations.remove(taglibUri);
@@ -832,32 +857,36 @@ public class TaglibFactory implements TemplateHashModel {
         InputSource inSrc = new InputSource();
         inSrc.setSystemId(systemId);
         inSrc.setByteStream(toCloseIgnoring(in));
-        
+
         SAXParserFactory factory = SAXParserFactory.newInstance();
         factory.setNamespaceAware(false);
         factory.setValidating(false); // Especially as we use dummy empty DTD-s
         XMLReader reader;
+
         try {
             reader = factory.newSAXParser().getXMLReader();
         } catch (ParserConfigurationException e) {
             // Not expected
             throw new RuntimeException("XML parser setup failed", e);
         }
+
         reader.setEntityResolver(new EmptyContentEntityResolver()); // To deal with referred DTD-s
         reader.setContentHandler(handler);
         reader.setErrorHandler(handler);
-        
+
         reader.parse(inSrc);
     }
 
     private static String resolveRelativeUri(String uri) throws TaglibGettingException {
         TemplateModel reqHash;
+
         try {
             reqHash = Environment.getCurrentEnvironment().getVariable(
                     FreemarkerServlet.KEY_REQUEST_PRIVATE);
         } catch (TemplateModelException e) {
             throw new TaglibGettingException("Failed to get FreemarkerServlet request information", e);
         }
+
         if (reqHash instanceof HttpRequestHashModel) {
             HttpServletRequest req =
                     ((HttpRequestHashModel) reqHash).getRequest();
@@ -876,6 +905,7 @@ public class TaglibFactory implements TemplateHashModel {
                 return '/' + uri;
             }
         }
+
         throw new TaglibGettingException(
                 "Can't resolve relative URI " + uri + " as request URL information is unavailable.");
     }
@@ -896,21 +926,26 @@ public class TaglibFactory implements TemplateHashModel {
         if (uri == null) {
             throw new IllegalArgumentException("null is not a valid URI");
         }
+
         if (uri.length() == 0) {
             throw new MalformedURLException("empty string is not a valid URI");
         }
+
         final char c0 = uri.charAt(0);
         if (c0 == '/') {
             return URL_TYPE_ABSOLUTE;
         }
+
         // Check if it conforms to RFC 3986 3.1 in order to qualify as ABS_URI
         if (c0 < 'a' || c0 > 'z') { // First char of scheme must be alpha
             return URL_TYPE_RELATIVE;
         }
+
         final int colon = uri.indexOf(':');
         if (colon == -1) { // Must have a colon
             return URL_TYPE_RELATIVE;
         }
+
         // Subsequent chars must be [a-z,0-9,+,-,.]
         for (int i = 1; i < colon; ++i) {
             final char c = uri.charAt(i);
@@ -918,13 +953,14 @@ public class TaglibFactory implements TemplateHashModel {
                 return URL_TYPE_RELATIVE;
             }
         }
+
         return URL_TYPE_FULL;
     }
 
     private static boolean isJarPath(final String uriPath) {
         return uriPath.endsWith(".jar") || uriPath.endsWith(".zip");
     }
-    
+
     private static boolean isJarUrl(URL url) {
         final String scheme = url.getProtocol();
         return "jar".equals(scheme) || "zip".equals(scheme)
@@ -937,6 +973,7 @@ public class TaglibFactory implements TemplateHashModel {
         if (relativeEntryPath.startsWith("/")) {
             relativeEntryPath = relativeEntryPath.substring(1);
         }
+
         try {
             return new URL(jarBaseEntryUrl, _StringUtil.URLPathEnc(relativeEntryPath, Charset.defaultCharset()));
         } catch (UnsupportedEncodingException e) {
@@ -952,12 +989,12 @@ public class TaglibFactory implements TemplateHashModel {
         if (!jarEntryDirPath.startsWith("/")) {
             jarEntryDirPath = "/" + jarEntryDirPath;
         }
-    
+
         // Known to be a problem:
         if (directory && !jarEntryDirPath.endsWith("/")) {
             jarEntryDirPath = jarEntryDirPath + "/";
         }
-    
+
         return jarEntryDirPath;
     }
 
@@ -972,11 +1009,11 @@ public class TaglibFactory implements TemplateHashModel {
         if (test_emulateNoUrlToFileConversions) {
             return null;
         }
-        
+
         if (!"file".equals(url.getProtocol())) {
             return null;
         }
-    
+
         String filePath;
         try {
             // Using URI instead of URL, so we get an URL-decoded path.
@@ -990,6 +1027,7 @@ public class TaglibFactory implements TemplateHashModel {
                 throw new BugException(e2);
             }
         }
+
         return new File(filePath);
     }
 
@@ -1001,6 +1039,7 @@ public class TaglibFactory implements TemplateHashModel {
     private JarFile servletContextResourceToFileOrNull(final String jarResourcePath) throws MalformedURLException,
             IOException {
         URL jarResourceUrl = servletContext.getResource(jarResourcePath);
+
         if (jarResourceUrl == null) {
             LOG.error("ServletContext resource URL was null (missing resource?): {}", jarResourcePath);
             return null;
@@ -1061,7 +1100,7 @@ public class TaglibFactory implements TemplateHashModel {
         }
         return tccl;
     }
-    
+
     private static boolean isDescendantOfOrSameAs(ClassLoader descendant, ClassLoader parent) {
         while (true) {
             if (descendant == null) {
@@ -1073,7 +1112,7 @@ public class TaglibFactory implements TemplateHashModel {
             descendant = descendant.getParent();
         }
     }
-    
+
     /**
      * A location within which we will look for {@code META-INF/**}{@code /*.tld}-s. Used in the parameter to
      * {@link #setMetaInfTldSources}. See concrete subclasses for more.
@@ -1103,9 +1142,9 @@ public class TaglibFactory implements TemplateHashModel {
      * Note that this TLD discovery mechanism is not part of the JSP specification.
      */
     public static final class ClasspathMetaInfTldSource extends MetaInfTldSource {
-        
+
         private final Pattern rootContainerPattern; 
-        
+
         /**
          * @param rootContainerPattern
          *            The pattern against which the classpath root container URL-s will be matched. For example, to only
@@ -1138,35 +1177,36 @@ public class TaglibFactory implements TemplateHashModel {
         public final static ClearMetaInfTldSource INSTANCE = new ClearMetaInfTldSource();
         private ClearMetaInfTldSource() { }
     }
-    
+
     private interface TldLocation {
-        
+
         /**
          * Reads the TLD file.
          * @return Not {@code null}
          */
         InputStream getInputStream() throws IOException;
-        
+
         /**
          * The absolute URL of the TLD file.
          * @return Not {@code null}
          */
         String getXmlSystemId() throws IOException;
+
     }
 
     private interface InputStreamFactory {
         InputStream getInputStream();
-    
+
     }
 
     private class ServletContextTldLocation implements TldLocation {
-        
+
         private final String fileResourcePath;
-    
+
         public ServletContextTldLocation(String fileResourcePath) {
             this.fileResourcePath = fileResourcePath;
         }
-    
+
         @Override
         public InputStream getInputStream() throws IOException {
             final InputStream in = servletContext.getResourceAsStream(fileResourcePath);
@@ -1175,44 +1215,43 @@ public class TaglibFactory implements TemplateHashModel {
             }
             return in;
         }
-    
+
         @Override
         public String getXmlSystemId() throws IOException {
             final URL url = servletContext.getResource(fileResourcePath);
             return url != null ? url.toExternalForm() : null;
         }
-        
+
         private IOException newResourceNotFoundException() {
             return new IOException("Resource not found: servletContext:" + fileResourcePath);
         }
-        
+
         @Override
         public final String toString() {
             return "servletContext:" + fileResourcePath;
         }
-    
+
     }
-    
 
     /**
      * Points to plain class loader resource (regardless of if in what classpath root container it's in).
      */
     private static class ClasspathTldLocation implements TldLocation {
-        
+
         private final String resourcePath;
-    
+
         public ClasspathTldLocation(String resourcePath) {
             if (!resourcePath.startsWith("/")) {
                 throw new IllegalArgumentException("\"resourcePath\" must start with /");
             }
             this.resourcePath = resourcePath;
         }
-    
+
         @Override
         public String toString() {
             return "classpath:" + resourcePath;
         }
-    
+
         @Override
         public InputStream getInputStream() throws IOException {
             ClassLoader tccl = tryGetThreadContextClassLoader();
@@ -1222,11 +1261,12 @@ public class TaglibFactory implements TemplateHashModel {
                     return in;
                 }
             }
-            
+
             final InputStream in = getClass().getResourceAsStream(resourcePath);
             if (in == null) {
                 throw newResourceNotFoundException();
             }
+
             return in;
         }
 
@@ -1239,15 +1279,15 @@ public class TaglibFactory implements TemplateHashModel {
                     return url.toExternalForm();
                 }
             }
-            
+
             final URL url = getClass().getResource(resourcePath);
             return url == null ? null : url.toExternalForm();
         }
-        
+
         private IOException newResourceNotFoundException() {
             return new IOException("Resource not found: classpath:" + resourcePath);
         }
-    
+
     }
 
     private abstract class JarEntryTldLocation implements TldLocation {
@@ -1259,14 +1299,14 @@ public class TaglibFactory implements TemplateHashModel {
         private final URL entryUrl;
         private final InputStreamFactory fallbackRawJarContentInputStreamFactory;
         private final String entryPath;
-        
+
         public JarEntryTldLocation(URL entryUrl, InputStreamFactory fallbackRawJarContentInputStreamFactory,
                 String entryPath) {
             if (entryUrl == null) {
                 _NullArgumentException.check(fallbackRawJarContentInputStreamFactory);
                 _NullArgumentException.check(entryPath);
             }
-            
+
             this.entryUrl = entryUrl;
             this.fallbackRawJarContentInputStreamFactory = fallbackRawJarContentInputStreamFactory;
             this.entryPath = entryPath != null ? normalizeJarEntryPath(entryPath, false) : null;
@@ -1295,7 +1335,7 @@ public class TaglibFactory implements TemplateHashModel {
                 }
                 // Retry with the fallbackRawJarContentInputStreamFactory comes.
             }
-            
+
             final String entryPath;
             if (this.entryPath != null) {
                 entryPath = this.entryPath;
@@ -1314,10 +1354,11 @@ public class TaglibFactory implements TemplateHashModel {
                                 Charset.defaultCharset().name()),
                         false);
             }
-            
+
             InputStream rawIn = null;
             ZipInputStream zipIn = null;
             boolean returnedZipIn = false;
+
             try {
                 rawIn = fallbackRawJarContentInputStreamFactory.getInputStream();
                 if (rawIn == null) {
@@ -1325,6 +1366,7 @@ public class TaglibFactory implements TemplateHashModel {
                             + ") says the resource doesn't exist.");
                 }
                 zipIn = new ZipInputStream(rawIn);
+
                 while (true) {
                     final ZipEntry macthedJarEntry = zipIn.getNextEntry();
                     if (macthedJarEntry == null) {
@@ -1346,34 +1388,34 @@ public class TaglibFactory implements TemplateHashModel {
                 }
             }
         }
-    
+
         @Override
         public String getXmlSystemId() {
             return entryUrl != null ? entryUrl.toExternalForm() : null;
         }
-    
+
         @Override
         public String toString() {
             return entryUrl != null
                     ? entryUrl.toExternalForm()
                     : "jar:{" + fallbackRawJarContentInputStreamFactory + "}!" + entryPath;
         }
-        
+
     }
-    
+
     private class JarEntryUrlTldLocation extends JarEntryTldLocation {
-        
+
         private JarEntryUrlTldLocation(URL entryUrl, InputStreamFactory fallbackRawJarContentInputStreamFactory) {
             super(entryUrl, fallbackRawJarContentInputStreamFactory, null);
         }
-        
+
     }
 
     /**
      * Points to a file entry inside a jar, with optional {@link ZipInputStream} fallback.
      */
     private class ServletContextJarEntryTldLocation extends JarEntryTldLocation {
-        
+
         /**
          * For creating instance based on the servlet context resource path of a jar.
          * While it tries to construct and use an URL that points directly to the target entry inside the jar, it will
@@ -1395,7 +1437,7 @@ public class TaglibFactory implements TemplateHashModel {
                     },
                     entryPath);
         }
-        
+
     }
 
     private static class FileTldLocation implements TldLocation {
@@ -1422,9 +1464,10 @@ public class TaglibFactory implements TemplateHashModel {
         }
 
     }
-    
+
     private static final class Taglib implements TemplateHashModel {
-        private final Map tagsAndFunctions;
+
+        private final Map<String, TemplateModel> tagsAndFunctions;
 
         Taglib(ServletContext ctx, TldLocation tldPath, ObjectWrapper wrapper) throws IOException, SAXException {
             tagsAndFunctions = parseToTagsAndFunctions(ctx, tldPath, wrapper);
@@ -1440,17 +1483,17 @@ public class TaglibFactory implements TemplateHashModel {
             return tagsAndFunctions.isEmpty();
         }
 
-        private static Map parseToTagsAndFunctions(
+        private static Map<String, TemplateModel> parseToTagsAndFunctions(
                 ServletContext ctx, TldLocation tldLocation, ObjectWrapper objectWrapper) throws IOException, SAXException {
             final TldParserForTaglibBuilding tldParser = new TldParserForTaglibBuilding(objectWrapper);
-            
+
             InputStream in = tldLocation.getInputStream();
             try {
                 parseXml(in, tldLocation.getXmlSystemId(), tldParser);
             } finally {
                 in.close();
             }
-            
+
             EventForwarding eventForwarding = EventForwarding.getInstance(ctx);
             if (eventForwarding != null) {
                 eventForwarding.addListeners(tldParser.getListeners());
@@ -1464,6 +1507,7 @@ public class TaglibFactory implements TemplateHashModel {
                                 "|   <listener-class>" + EventForwarding.class.getName() + "</listener-class>\n" +
                                 "| </listener>", null);
             }
+
             return tldParser.getTagsAndFunctions();
         }
     }
@@ -1587,12 +1631,12 @@ public class TaglibFactory implements TemplateHashModel {
         private final DefaultObjectWrapper defaultObjectWrapper;
 
         private final Map<String, TemplateModel> tagsAndFunctions = new HashMap<>();
-        private final List listeners = new ArrayList();
+        private final List<Object> listeners = new ArrayList<>();
 
         private Locator locator;
         private StringBuilder cDataCollector;
 
-        private Stack stack = new Stack();
+        private Stack<String> stack = new Stack<>();
 
         private String tagNameCData;
         private String tagClassCData;
@@ -1621,7 +1665,7 @@ public class TaglibFactory implements TemplateHashModel {
             return tagsAndFunctions;
         }
 
-        List getListeners() {
+        List<Object> getListeners() {
             return listeners;
         }
 
@@ -1676,7 +1720,7 @@ public class TaglibFactory implements TemplateHashModel {
                     checkChildElementNotNull(qName, E_NAME, tagNameCData);
                     checkChildElementNotNull(qName, E_TAG_CLASS, tagClassCData);
 
-                    final Class tagClass = resoveClassFromTLD(tagClassCData, "custom tag", tagNameCData);
+                    final Class<?> tagClass = resoveClassFromTLD(tagClassCData, "custom tag", tagNameCData);
 
                     final TemplateModel customTagModel;
                     try {
@@ -1712,7 +1756,7 @@ public class TaglibFactory implements TemplateHashModel {
                     checkChildElementNotNull(qName, E_FUNCTION_SIGNATURE, functionSignatureCData);
                     checkChildElementNotNull(qName, E_NAME, functionNameCData);
 
-                    final Class functionClass = resoveClassFromTLD(
+                    final Class<?> functionClass = resoveClassFromTLD(
                             functionClassCData, "custom EL function", functionNameCData);
 
                     final Method functionMethod;
@@ -1763,7 +1807,7 @@ public class TaglibFactory implements TemplateHashModel {
                 } else if (E_LISTENER.equals(qName)) {
                     checkChildElementNotNull(qName, E_LISTENER_CLASS, listenerClassCData);
 
-                    final Class listenerClass = resoveClassFromTLD(listenerClassCData, E_LISTENER, null);
+                    final Class<?> listenerClass = resoveClassFromTLD(listenerClassCData, E_LISTENER, null);
 
                     final Object listener;
                     try {
@@ -1783,7 +1827,7 @@ public class TaglibFactory implements TemplateHashModel {
 
             stack.pop();
         }
-        
+
         private String pullCData() {
             String r = cDataCollector.toString().trim();
             cDataCollector = null;
@@ -1799,7 +1843,7 @@ public class TaglibFactory implements TemplateHashModel {
             }
         }
 
-        private Class resoveClassFromTLD(String className, String entryType, String entryName)
+        private Class<?> resoveClassFromTLD(String className, String entryType, String entryName)
                 throws TldParsingSAXException {
             try {
                 return _ClassUtil.forName(className);
@@ -1837,7 +1881,7 @@ public class TaglibFactory implements TemplateHashModel {
      * Dummy resolver that returns 0 length content for all requests.
      */
     private static final class EmptyContentEntityResolver implements EntityResolver {
-        
+
         @Override
         public InputSource resolveEntity(String publicId, String systemId) {
             InputSource is = new InputSource(new ByteArrayInputStream(new byte[0]));
@@ -1851,28 +1895,30 @@ public class TaglibFactory implements TemplateHashModel {
      * Redefines {@code SAXParseException#toString()} and {@code SAXParseException#getCause()} because it's broken on
      * Java 1.6 and earlier.
      */
+    @SuppressWarnings("serial")
     private static class TldParsingSAXException extends SAXParseException {
-    
+
         private final Throwable cause;
-    
+
         TldParsingSAXException(String message, Locator locator) {
             this(message, locator, null);
         }
-    
+
         TldParsingSAXException(String message, Locator locator, Throwable e) {
             super(message, locator, e instanceof Exception ? (Exception) e : new Exception(
                     "Unchecked exception; see cause", e));
             cause = e;
         }
-    
+
         @Override
         public String toString() {
             StringBuilder sb = new StringBuilder(getClass().getName());
             sb.append(": ");
             int startLn = sb.length();
-    
+
             String systemId = getSystemId();
             String publicId = getPublicId();
+
             if (systemId != null || publicId != null) {
                 sb.append("In ");
                 if (systemId != null) {
@@ -1888,7 +1934,7 @@ public class TaglibFactory implements TemplateHashModel {
                     }
                 }
             }
-    
+
             int line = getLineNumber();
             if (line != -1) {
                 sb.append(sb.length() != startLn ? ", at " : "At ");
@@ -1900,7 +1946,7 @@ public class TaglibFactory implements TemplateHashModel {
                     sb.append(col);
                 }
             }
-    
+
             String message = getLocalizedMessage();
             if (message != null) {
                 if (sb.length() != startLn) {
@@ -1908,19 +1954,19 @@ public class TaglibFactory implements TemplateHashModel {
                 }
                 sb.append(message);
             }
-    
+
             return sb.toString();
         }
-    
+
         @Override
         public Throwable getCause() {
             Throwable superCause = super.getCause();
             return superCause == null ? cause : superCause;
         }
-    
+
     }
-    
-    private static class URLWithExternalForm implements Comparable {
+
+    private static class URLWithExternalForm implements Comparable<URLWithExternalForm> {
 
         private final URL url;
         private final String externalForm;
@@ -1957,12 +2003,13 @@ public class TaglibFactory implements TemplateHashModel {
         }
 
         @Override
-        public int compareTo(Object that) {
-            return getExternalForm().compareTo(((URLWithExternalForm) that).getExternalForm());
+        public int compareTo(URLWithExternalForm that) {
+            return getExternalForm().compareTo(that.getExternalForm());
         }
 
     }
-    
+
+    @SuppressWarnings("serial")
     private static class TaglibGettingException extends Exception {
 
         public TaglibGettingException(String message, Throwable cause) {