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

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

      
    
Rootfs path

      
    
Size
11454 (11.2 KB)
MD5
375a91f3b72dd4258dc61e81a87c569e
SHA1
2e073b89fef5ffef4ee0bdd9cdc5fb30af3eb814
SHA256
7ca99f9bb0f821ba1c73a86b136d3d6fd11f789fdb724f97ad952257ad28b2e0
SHA512

      
    
SHA1_git
f226616891dfc92d6400f6899c970234e445632a
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
ELFunctionMapper.java | 11.2 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.compiler; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import jakarta.servlet.jsp.tagext.FunctionInfo; import org.apache.jasper.JasperException; /** * This class generates functions mappers for the EL expressions in the page. Instead of a global mapper, a mapper is * used for each call to EL evaluator, thus avoiding the prefix overlapping and redefinition issues. */ public class ELFunctionMapper { private int currFunc = 0; private StringBuilder ds; // Contains codes to initialize the functions mappers. private StringBuilder ss; // Contains declarations of the functions mappers. /** * Creates the functions mappers for all EL expressions in the JSP page. * * @param page The current compilation unit. * * @throws JasperException EL error */ public static void map(Node.Nodes page) throws JasperException { ELFunctionMapper map = new ELFunctionMapper(); map.ds = new StringBuilder(); map.ss = new StringBuilder(); page.visit(map.new ELFunctionVisitor()); // Append the declarations to the root node String ds = map.ds.toString(); if (!ds.isEmpty()) { Node root = page.getRoot(); @SuppressWarnings("unused") Node unused = new Node.Declaration(map.ss.toString(), null, root); unused = new Node.Declaration("static { " + ds + "} ", null, root); } } /** * A visitor for the page. The places where EL is allowed are scanned for functions, and if found functions mappers * are created. */ private class ELFunctionVisitor extends Node.Visitor { /** * Use a global name map to facilitate reuse of function maps. The key used is prefix:function:uri. */ private final Map<String,String> gMap = new HashMap<>(); @Override public void visit(Node.ParamAction n) throws JasperException { doMap(n.getValue()); visitBody(n); } @Override public void visit(Node.IncludeAction n) throws JasperException { doMap(n.getPage()); visitBody(n); } @Override public void visit(Node.ForwardAction n) throws JasperException { doMap(n.getPage()); visitBody(n); } @Override public void visit(Node.SetProperty n) throws JasperException { doMap(n.getValue()); visitBody(n); } @Override public void visit(Node.UseBean n) throws JasperException { doMap(n.getBeanName()); visitBody(n); } @Override public void visit(Node.JspElement n) throws JasperException { Node.JspAttribute[] attrs = n.getJspAttributes(); for (int i = 0; attrs != null && i < attrs.length; i++) { doMap(attrs[i]); } doMap(n.getNameAttribute()); visitBody(n); } @Override public void visit(Node.UninterpretedTag n) throws JasperException { Node.JspAttribute[] attrs = n.getJspAttributes(); for (int i = 0; attrs != null && i < attrs.length; i++) { doMap(attrs[i]); } visitBody(n); } @Override public void visit(Node.CustomTag n) throws JasperException { Node.JspAttribute[] attrs = n.getJspAttributes(); for (int i = 0; attrs != null && i < attrs.length; i++) { doMap(attrs[i]); } visitBody(n); } @Override public void visit(Node.ELExpression n) throws JasperException { doMap(n.getEL()); } private void doMap(Node.JspAttribute attr) throws JasperException { if (attr != null) { doMap(attr.getEL()); } } /** * Creates function mappers, if needed, from ELNodes */ private void doMap(ELNode.Nodes el) throws JasperException { // Only care about functions in ELNode's class Fvisitor extends ELNode.Visitor { private final List<ELNode.Function> funcs = new ArrayList<>(); private final Set<String> keySet = new HashSet<>(); @Override public void visit(ELNode.Function n) throws JasperException { String key = n.getPrefix() + ":" + n.getName(); if (keySet.add(key)) { funcs.add(n); } } } if (el == null) { return; } // First locate all unique functions in this EL Fvisitor fv = new Fvisitor(); el.visit(fv); List<ELNode.Function> functions = fv.funcs; if (functions.isEmpty()) { return; } // Reuse a previous map if possible String decName = matchMap(functions); if (decName != null) { el.setMapName(decName); return; } // Generate declaration for the map statically decName = getMapName(); ss.append("private static org.apache.jasper.runtime.ProtectedFunctionMapper ").append(decName) .append("; "); ds.append(" ").append(decName).append("= "); ds.append("org.apache.jasper.runtime.ProtectedFunctionMapper"); // Special case if there is only one function in the map String funcMethod; if (functions.size() == 1) { funcMethod = ".getMapForFunction"; } else { ds.append(".getInstance(); "); funcMethod = " " + decName + ".mapFunction"; } // Setup arguments for either getMapForFunction or mapFunction for (ELNode.Function f : functions) { FunctionInfo funcInfo = f.getFunctionInfo(); String fnQName = f.getPrefix() + ":" + f.getName(); if (funcInfo == null) { // Added via Lambda or ImportHandler. EL will expect a // function mapper even if one isn't used so just pass null ds.append(funcMethod).append("(null, null, null, null); "); } else { ds.append(funcMethod).append("(\"").append(fnQName).append("\", "); ds.append(getCanonicalName(funcInfo.getFunctionClass())).append(".class, ").append('\"'); ds.append(f.getMethodName()).append("\", ").append("new Class[] {"); String[] params = f.getParameters(); for (int k = 0; k < params.length; k++) { if (k != 0) { ds.append(", "); } int iArray = params[k].indexOf('['); if (iArray < 0) { ds.append(params[k]).append(".class"); } else { String baseType = params[k].substring(0, iArray); ds.append("java.lang.reflect.Array.newInstance("); ds.append(baseType); ds.append(".class,"); // Count the number of array dimension int aCount = 0; for (int jj = iArray; jj < params[k].length(); jj++) { if (params[k].charAt(jj) == '[') { aCount++; } } if (aCount == 1) { ds.append("0).getClass()"); } else { ds.append("new int[").append(aCount).append("]).getClass()"); } } } ds.append("}); "); } // Put the current name in the global function map gMap.put(fnQName + ':' + f.getUri(), decName); } el.setMapName(decName); } /** * Find the name of the function mapper for an EL. Reuse a previously generated one if possible. * * @param functions A List of ELNode.Function instances that represents the functions in an EL * * @return A previous generated function mapper name that can be used by this EL; null if none found. */ private String matchMap(List<ELNode.Function> functions) { String mapName = null; for (ELNode.Function f : functions) { String temName = gMap.get(f.getPrefix() + ':' + f.getName() + ':' + f.getUri()); if (temName == null) { return null; } if (mapName == null) { mapName = temName; } else if (!temName.equals(mapName)) { // If not all in the previous match, then no match. return null; } } return mapName; } /* * @return A unique name for a function mapper. */ private String getMapName() { return "_jspx_fnmap_" + currFunc++; } /** * Convert a binary class name into a canonical one that can be used when generating Java source code. * * @param className Binary class name * * @return Canonical equivalent */ private String getCanonicalName(String className) throws JasperException { Class<?> clazz; ClassLoader tccl = Thread.currentThread().getContextClassLoader(); try { clazz = Class.forName(className, false, tccl); } catch (ClassNotFoundException e) { throw new JasperException(e); } return clazz.getCanonicalName(); } } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
11.27
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