ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/jasper/JspCompilationContext.java

Path
ttomcat-1778514358873.zip-extract/apache-tomcat-11.0.18-src/java/org/apache/jasper/JspCompilationContext.java
Status
scanned
Type
file
Name
JspCompilationContext.java
Extension
.java
Programming language
Java
Mime type
text/plain
File type
ASCII text, with CRLF line terminators
Tag

      
    
Rootfs path

      
    
Size
25247 (24.7 KB)
MD5
3e9065a39f40e2931c508cd58c69a542
SHA1
0dbf9d7fcdb146bab01d9e8436559643b3ac45b0
SHA256
f296a05e3dd340ae836c8dfa8e6ec71a2d5e30361b4f3aa5f7f71ade4480e9d1
SHA512

      
    
SHA1_git
b313c9f419a49034f9dbbc47f64c8a2e35251d67
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
JspCompilationContext.java | 24.7 KB |

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jasper; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; import java.util.Set; import java.util.jar.JarEntry; import jakarta.servlet.ServletContext; import jakarta.servlet.jsp.tagext.TagInfo; import org.apache.jasper.compiler.Compiler; import org.apache.jasper.compiler.JspRuntimeContext; import org.apache.jasper.compiler.JspUtil; import org.apache.jasper.compiler.Localizer; import org.apache.jasper.compiler.ServletWriter; import org.apache.jasper.servlet.JasperLoader; import org.apache.jasper.servlet.JspServletWrapper; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.Jar; import org.apache.tomcat.util.descriptor.tld.TldResourcePath; /** * A placeholder for various things that are used throughout the JSP engine. This is a per-request/per-context data * structure. Some of the instance variables are set at different points. Most of the path-related stuff is here - * mangling names, versions, dirs, loading resources and dealing with uris. */ public class JspCompilationContext { private final Log log = LogFactory.getLog(JspCompilationContext.class); // must not be static private String className; private final String jspUri; private String basePackageName; private String derivedPackageName; private String servletJavaFileName; private String javaPath; private String classFileName; private ServletWriter writer; private final Options options; private final JspServletWrapper jsw; private Compiler jspCompiler; private String classPath; private final String baseURI; private String outputDir; private final ServletContext context; private ClassLoader loader; private final JspRuntimeContext rctxt; private volatile boolean removed = false; // volatile so changes are visible when multiple threads request a JSP file // that has been modified private volatile URLClassLoader jspLoader; private URL baseUrl; private Class<?> servletClass; private final boolean isTagFile; private boolean protoTypeMode; private TagInfo tagInfo; private Jar tagJar; // jspURI _must_ be relative to the context public JspCompilationContext(String jspUri, Options options, ServletContext context, JspServletWrapper jsw, JspRuntimeContext rctxt) { this(jspUri, null, options, context, jsw, rctxt, null, false); } public JspCompilationContext(String tagfile, TagInfo tagInfo, Options options, ServletContext context, JspServletWrapper jsw, JspRuntimeContext rctxt, Jar tagJar) { this(tagfile, tagInfo, options, context, jsw, rctxt, tagJar, true); } private JspCompilationContext(String jspUri, TagInfo tagInfo, Options options, ServletContext context, JspServletWrapper jsw, JspRuntimeContext rctxt, Jar tagJar, boolean isTagFile) { this.jspUri = canonicalURI(jspUri); this.options = options; this.jsw = jsw; this.context = context; String baseURI = jspUri.substring(0, jspUri.lastIndexOf('/') + 1); // hack fix for resolveRelativeURI if (baseURI.isEmpty()) { baseURI = "/"; } else if (baseURI.charAt(0) != '/') { // strip the base slash since it will be combined with the // uriBase to generate a file baseURI = "/" + baseURI; } if (baseURI.charAt(baseURI.length() - 1) != '/') { baseURI += '/'; } this.baseURI = baseURI; this.rctxt = rctxt; this.basePackageName = options.getGeneratedJspPackageName(); this.tagInfo = tagInfo; this.tagJar = tagJar; this.isTagFile = isTagFile; } /* ==================== Methods to override ==================== */ // ---------- Class path and loader ---------- /** * @return the classpath that is passed off to the Java compiler. */ public String getClassPath() { if (classPath != null) { return classPath; } return rctxt.getClassPath(); } /** * The classpath that is passed off to the Java compiler. * * @param classPath The class path to use */ public void setClassPath(String classPath) { this.classPath = classPath; } /** * What class loader to use for loading classes while compiling this JSP? * * @return the class loader used to load all compiled classes */ public ClassLoader getClassLoader() { if (loader != null) { return loader; } return rctxt.getParentClassLoader(); } public void setClassLoader(ClassLoader loader) { this.loader = loader; } public ClassLoader getJspLoader() { if (jspLoader == null) { jspLoader = new JasperLoader(new URL[] { baseUrl }, getClassLoader(), basePackageName); } return jspLoader; } public void clearJspLoader() { jspLoader = null; } // ---------- Input/Output ---------- /** * The output directory to generate code into. The output directory is make up of the scratch directory, which is * provided in Options, plus the directory derived from the package name. * * @return the output directory in which the generated sources are placed */ public String getOutputDir() { if (outputDir == null) { createOutputDir(); } return outputDir; } /** * Create a "Compiler" object based on some init param data. This is not done yet. Right now we're just hardcoding * the actual compilers that are created. * * @return the Java compiler wrapper */ public Compiler createCompiler() { if (jspCompiler != null) { return jspCompiler; } if (options.getCompilerClassName() != null) { jspCompiler = createCompiler(options.getCompilerClassName()); } else { if (options.getCompiler() == null) { jspCompiler = createCompiler("org.apache.jasper.compiler.JDTCompiler"); if (jspCompiler == null) { jspCompiler = createCompiler("org.apache.jasper.compiler.AntCompiler"); } } else { jspCompiler = createCompiler("org.apache.jasper.compiler.AntCompiler"); if (jspCompiler == null) { jspCompiler = createCompiler("org.apache.jasper.compiler.JDTCompiler"); } } } if (jspCompiler == null) { throw new IllegalStateException(Localizer.getMessage("jsp.error.compiler.config", options.getCompilerClassName(), options.getCompiler())); } jspCompiler.init(this, jsw); return jspCompiler; } protected Compiler createCompiler(String className) { Compiler compiler = null; try { compiler = (Compiler) Class.forName(className).getConstructor().newInstance(); } catch (NoClassDefFoundError | ClassNotFoundException e) { if (log.isDebugEnabled()) { log.debug(Localizer.getMessage("jsp.error.compiler"), e); } } catch (ReflectiveOperationException e) { log.warn(Localizer.getMessage("jsp.error.compiler"), e); } return compiler; } public Compiler getCompiler() { return jspCompiler; } // ---------- Access resources in the webapp ---------- /** * Get the full value of a URI relative to this compilations context uses current file as the base. * * @param uri The relative URI * * @return absolute URI */ public String resolveRelativeUri(String uri) { // sometimes we get uri's massaged from File(String), so check for // a root directory separator char if (uri.startsWith("/") || uri.startsWith(File.separator)) { return uri; } else { return baseURI + uri; } } /** * Gets a resource as a stream, relative to the meanings of this context's implementation. * * @param res the resource to look for * * @return a null if the resource cannot be found or represented as an InputStream. */ public java.io.InputStream getResourceAsStream(String res) { return context.getResourceAsStream(canonicalURI(res)); } public URL getResource(String res) throws MalformedURLException { return context.getResource(canonicalURI(res)); } public Set<String> getResourcePaths(String path) { return context.getResourcePaths(canonicalURI(path)); } /** * Gets the actual path of a URI relative to the context of the compilation. * * @param path The webapp path * * @return the corresponding path in the filesystem */ public String getRealPath(String path) { if (context != null) { return context.getRealPath(path); } return path; } /** * Returns the JAR file in which the tag file for which this JspCompilationContext was created is packaged, or null * if this JspCompilationContext does not correspond to a tag file, or if the corresponding tag file is not packaged * in a JAR. * * @return a JAR file */ public Jar getTagFileJar() { return this.tagJar; } public void setTagFileJar(Jar tagJar) { this.tagJar = tagJar; } /* ==================== Common implementation ==================== */ /** * Just the class name (does not include package name) of the generated class. * * @return the class name */ public String getServletClassName() { if (className != null) { return className; } if (isTagFile) { className = tagInfo.getTagClassName(); int lastIndex = className.lastIndexOf('.'); if (lastIndex != -1) { className = className.substring(lastIndex + 1); } } else { int iSep = jspUri.lastIndexOf('/') + 1; className = JspUtil.makeJavaIdentifier(jspUri.substring(iSep)); } return className; } public void setServletClassName(String className) { this.className = className; } /** * Path of the JSP URI. Note that this is not a file name. This is the context rooted URI of the JSP file. * * @return the path to the JSP */ public String getJspFile() { return jspUri; } public Long getLastModified(String resource) { return getLastModified(resource, tagJar); } public Long getLastModified(String resource, Jar tagJar) { long result = -1; URLConnection uc = null; try { if (tagJar != null) { if (resource.startsWith("/")) { resource = resource.substring(1); } result = tagJar.getLastModified(resource); } else { URL jspUrl = getResource(resource); if (jspUrl == null) { incrementRemoved(); return Long.valueOf(result); } uc = jspUrl.openConnection(); if (uc instanceof JarURLConnection) { JarEntry jarEntry = ((JarURLConnection) uc).getJarEntry(); if (jarEntry != null) { result = jarEntry.getTime(); } else { result = uc.getLastModified(); } } else { result = uc.getLastModified(); } } } catch (IOException ioe) { if (log.isDebugEnabled()) { log.debug(Localizer.getMessage("jsp.error.lastModified", getJspFile()), ioe); } } finally { if (uc != null) { try { uc.getInputStream().close(); } catch (IOException ioe) { if (log.isDebugEnabled()) { log.debug(Localizer.getMessage("jsp.error.lastModified", getJspFile()), ioe); } result = -1; } } } return Long.valueOf(result); } public boolean isTagFile() { return isTagFile; } public TagInfo getTagInfo() { return tagInfo; } public void setTagInfo(TagInfo tagi) { tagInfo = tagi; } /** * @return <code>true</code> if we are compiling a tag file in prototype mode. ie we only generate codes with class * for the tag handler with empty method bodies. */ public boolean isPrototypeMode() { return protoTypeMode; } public void setPrototypeMode(boolean pm) { protoTypeMode = pm; } /** * Package name for the generated class is made up of the base package name, which is user settable, and the derived * package name. The derived package name directly mirrors the file hierarchy of the JSP page. * * @return the package name */ public String getServletPackageName() { if (isTagFile()) { String className = tagInfo.getTagClassName(); int lastIndex = className.lastIndexOf('.'); String packageName = ""; if (lastIndex != -1) { packageName = className.substring(0, lastIndex); } return packageName; } else { String dPackageName = getDerivedPackageName(); if (dPackageName.isEmpty()) { return basePackageName; } return basePackageName + '.' + getDerivedPackageName(); } } protected String getDerivedPackageName() { if (derivedPackageName == null) { int iSep = jspUri.lastIndexOf('/'); derivedPackageName = (iSep > 0) ? JspUtil.makeJavaPackage(jspUri.substring(1, iSep)) : ""; } return derivedPackageName; } /** * @return The base package name into which all servlet and associated code is generated */ public String getBasePackageName() { return basePackageName; } /** * The package name into which the servlet class is generated. * * @param basePackageName The package name to use */ public void setBasePackageName(String basePackageName) { this.basePackageName = basePackageName; } /** * @return Full path name of the Java file into which the servlet is being generated. */ public String getServletJavaFileName() { if (servletJavaFileName == null) { servletJavaFileName = getOutputDir() + getServletClassName() + ".java"; } return servletJavaFileName; } /** * @return the Options object for this context. */ public Options getOptions() { return options; } public ServletContext getServletContext() { return context; } public JspRuntimeContext getRuntimeContext() { return rctxt; } /** * @return the path of the Java file relative to the work directory. */ public String getJavaPath() { if (javaPath != null) { return javaPath; } if (isTagFile()) { String tagName = tagInfo.getTagClassName(); javaPath = tagName.replace('.', '/') + ".java"; } else { javaPath = getServletPackageName().replace('.', '/') + '/' + getServletClassName() + ".java"; } return javaPath; } public String getClassFileName() { if (classFileName == null) { classFileName = getOutputDir() + getServletClassName() + ".class"; } return classFileName; } /** * @return the writer that is used to write the generated Servlet source. */ public ServletWriter getWriter() { return writer; } public void setWriter(ServletWriter writer) { this.writer = writer; } /** * Gets the 'location' of the TLD associated with the given taglib 'uri'. * * @param uri The taglib URI * * @return An array of two Strings: The first element denotes the real path to the TLD. If the path to the TLD * points to a jar file, then the second element denotes the name of the TLD entry in the jar file. * Returns null if the given uri is not associated with any tag library 'exposed' in the web * application. */ public TldResourcePath getTldResourcePath(String uri) { return getOptions().getTldCache().getTldResourcePath(uri); } /** * @return <code>true</code> if generated code is kept. */ public boolean keepGenerated() { return getOptions().getKeepGenerated(); } // ==================== Removal ==================== public void incrementRemoved() { if (!removed && rctxt != null) { rctxt.removeWrapper(jspUri); } removed = true; } public boolean isRemoved() { return removed; } // ==================== Compile and reload ==================== public void compile() throws JasperException, FileNotFoundException { createCompiler(); if (jspCompiler.isOutDated()) { if (isRemoved()) { throw new FileNotFoundException(jspUri); } try { jspCompiler.removeGeneratedFiles(); jspLoader = null; jspCompiler.compile(); jsw.setCompilationException(null); } catch (JasperException ex) { // Cache compilation exception jsw.setCompilationException(ex); if (options.getDevelopment() && options.getRecompileOnFail()) { // Force a recompilation attempt on next access jsw.setLastModificationTest(-1); } throw ex; } catch (FileNotFoundException fnfe) { // Re-throw to let caller handle this - will result in a 404 throw fnfe; } catch (Exception e) { JasperException je = new JasperException(Localizer.getMessage("jsp.error.unable.compile"), e); // Cache compilation exception jsw.setCompilationException(je); throw je; } finally { jsw.setReload(true); } } } // ==================== Manipulating the class ==================== public Class<?> load() throws JasperException { try { getJspLoader(); String name = getFQCN(); servletClass = jspLoader.loadClass(name); } catch (ClassNotFoundException cex) { throw new JasperException(Localizer.getMessage("jsp.error.unable.load"), cex); } catch (Exception e) { throw new JasperException(Localizer.getMessage("jsp.error.unable.compile"), e); } removed = false; return servletClass; } public String getFQCN() { String name; if (isTagFile()) { name = tagInfo.getTagClassName(); } else { name = getServletPackageName() + "." + getServletClassName(); } return name; } // ==================== protected methods ==================== private static final Object outputDirLock = new Object(); public void checkOutputDir() { if (outputDir != null) { if (!(new File(outputDir)).exists()) { makeOutputDir(); } } else { createOutputDir(); } } protected boolean makeOutputDir() { synchronized (outputDirLock) { File outDirFile = new File(outputDir); return (outDirFile.mkdirs() || outDirFile.isDirectory()); } } protected void createOutputDir() { String path; if (isTagFile()) { String tagName = tagInfo.getTagClassName(); path = tagName.replace('.', File.separatorChar); path = path.substring(0, path.lastIndexOf(File.separatorChar)); } else { path = getServletPackageName().replace('.', File.separatorChar); } // Append servlet or tag handler path to scratch dir try { File base = options.getScratchDir(); baseUrl = base.toURI().toURL(); outputDir = base.getAbsolutePath() + File.separator + path + File.separator; if (!makeOutputDir()) { log.error(Localizer.getMessage("jsp.error.outputfolder.detail", outputDir)); throw new IllegalStateException(Localizer.getMessage("jsp.error.outputfolder")); } } catch (MalformedURLException e) { throw new IllegalStateException(Localizer.getMessage("jsp.error.outputfolder"), e); } } protected static boolean isPathSeparator(char c) { return (c == '/' || c == '\\'); } protected static String canonicalURI(String s) { if (s == null) { return null; } StringBuilder result = new StringBuilder(); final int len = s.length(); int pos = 0; while (pos < len) { char c = s.charAt(pos); if (isPathSeparator(c)) { /* * multiple path separators. 'foo///bar' -> 'foo/bar' */ while (pos + 1 < len && isPathSeparator(s.charAt(pos + 1))) { ++pos; } if (pos + 1 < len && s.charAt(pos + 1) == '.') { /* * a single dot at the end of the path - we are done. */ if (pos + 2 >= len) { break; } switch (s.charAt(pos + 2)) { /* * self directory in path foo/./bar -> foo/bar */ case '/': case '\\': pos += 2; continue; /* * two dots in a path: go back one hierarchy. foo/bar/../baz -> foo/baz */ case '.': // only if we have exactly _two_ dots. if (pos + 3 < len && isPathSeparator(s.charAt(pos + 3))) { pos += 3; int separatorPos = result.length() - 1; while (separatorPos >= 0 && !isPathSeparator(result.charAt(separatorPos))) { --separatorPos; } if (separatorPos >= 0) { result.setLength(separatorPos); } continue; } } } } result.append(c); ++pos; } return result.toString(); } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
5.43
Copyrights

      
    
Holders

      
    
Authors

      
    
License detections License expression License expression SPDX
apache_2_0-4bde3f57-78aa-4201-96bf-531cba09e7de apache-2.0 Apache-2.0
URL Start line End line
http://www.apache.org/licenses/LICENSE-2.0 9 9