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

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

      
    
Rootfs path

      
    
Size
10927 (10.7 KB)
MD5
086260a0d0250ee3eb0f88218368cf79
SHA1
46d58034558032fc7edfcc9d1b4b4c1dc4cc8f81
SHA256
b8e8d3da91cc1d3755566cec0626175e3e16c045e00db4545a451dca5895db5c
SHA512

      
    
SHA1_git
c24adb33de0b70f20ab47d56d81c8476ecd2d6c5
Is binary

      
    
Is text
True
Is archive

      
    
Is media

      
    
Is legal

      
    
Is manifest

      
    
Is readme

      
    
Is top level

      
    
Is key file

      
    
JasperELResolver.java | 10.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.el; import java.lang.reflect.Method; import java.util.List; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; import jakarta.el.ArrayELResolver; import jakarta.el.BeanELResolver; import jakarta.el.CompositeELResolver; import jakarta.el.ELContext; import jakarta.el.ELException; import jakarta.el.ELResolver; import jakarta.el.ListELResolver; import jakarta.el.MapELResolver; import jakarta.el.PropertyNotFoundException; import jakarta.el.RecordELResolver; import jakarta.el.ResourceBundleELResolver; import jakarta.el.StaticFieldELResolver; import jakarta.servlet.jsp.el.ImplicitObjectELResolver; import jakarta.servlet.jsp.el.ImportELResolver; import jakarta.servlet.jsp.el.NotFoundELResolver; import jakarta.servlet.jsp.el.ScopedAttributeELResolver; import org.apache.jasper.runtime.ExceptionUtils; import org.apache.jasper.runtime.JspRuntimeLibrary; /** * Jasper-specific CompositeELResolver that optimizes certain functions to avoid unnecessary resolver calls. */ public class JasperELResolver extends CompositeELResolver { // Keep aligned with class under test private static final int STANDARD_RESOLVERS_COUNT = 11; private final AtomicInteger resolversSize = new AtomicInteger(0); private volatile ELResolver[] resolvers; private final int appResolversSize; public JasperELResolver(List<ELResolver> appResolvers, ELResolver streamResolver) { appResolversSize = appResolvers.size(); resolvers = new ELResolver[appResolversSize + STANDARD_RESOLVERS_COUNT]; add(new ImplicitObjectELResolver()); for (ELResolver appResolver : appResolvers) { add(appResolver); } add(streamResolver); add(new StaticFieldELResolver()); add(new MapELResolver()); add(new ResourceBundleELResolver()); add(new ListELResolver()); add(new ArrayELResolver()); if (JspRuntimeLibrary.GRAAL) { add(new GraalBeanELResolver()); } add(new RecordELResolver()); add(new BeanELResolver()); add(new ScopedAttributeELResolver()); add(new ImportELResolver()); add(new NotFoundELResolver()); } @Override public synchronized void add(ELResolver elResolver) { super.add(elResolver); int size = resolversSize.get(); if (resolvers.length > size) { resolvers[size] = elResolver; } else { ELResolver[] nr = new ELResolver[size + 1]; System.arraycopy(resolvers, 0, nr, 0, size); nr[size] = elResolver; resolvers = nr; } resolversSize.incrementAndGet(); } @Override public Object getValue(ELContext context, Object base, Object property) throws NullPointerException, PropertyNotFoundException, ELException { context.setPropertyResolved(false); int start; Object result; if (base == null) { // call implicit and app resolvers int index = 1 /* implicit */ + appResolversSize; for (int i = 0; i < index; i++) { result = resolvers[i].getValue(context, null, property); if (context.isPropertyResolved()) { return result; } } // skip stream, static and collection-based resolvers (map, // resource, list, array) and bean start = index + 7; if (JspRuntimeLibrary.GRAAL) { start++; } } else { // skip implicit resolver only start = 1; } int size = resolversSize.get(); for (int i = start; i < size; i++) { result = resolvers[i].getValue(context, base, property); if (context.isPropertyResolved()) { return result; } } return null; } @Override public Object invoke(ELContext context, Object base, Object method, Class<?>[] paramTypes, Object[] params) { String targetMethod = coerceToString(method); if (targetMethod.isEmpty()) { throw new ELException(new NoSuchMethodException()); } context.setPropertyResolved(false); Object result; // skip implicit and call app resolvers, stream resolver and static // resolver int index = 1 /* implicit */ + appResolversSize + 2 /* stream + static */; for (int i = 1; i < index; i++) { result = resolvers[i].invoke(context, base, targetMethod, paramTypes, params); if (context.isPropertyResolved()) { return result; } } // skip collection (map, resource, list, and array) resolvers index += 4; // call bean and the rest of resolvers int size = resolversSize.get(); for (int i = index; i < size; i++) { result = resolvers[i].invoke(context, base, targetMethod, paramTypes, params); if (context.isPropertyResolved()) { return result; } } return null; } /* * Copied from org.apache.el.lang.ELSupport#coerceToString(ELContext,Object) */ private static String coerceToString(final Object obj) { if (obj == null) { return ""; } else if (obj instanceof String) { return (String) obj; } else if (obj instanceof Enum<?>) { return ((Enum<?>) obj).name(); } else { return obj.toString(); } } /** * Extend ELResolver for Graal to avoid bean info use if possible, as BeanELResolver needs manual reflection * configuration. */ public static class GraalBeanELResolver extends ELResolver { @Override public Object getValue(ELContext context, Object base, Object property) { Objects.requireNonNull(context); if (base == null || property == null) { return null; } Object value = null; Method method = getReadMethod(base.getClass(), property.toString()); if (method != null) { context.setPropertyResolved(base, property); try { method.setAccessible(true); value = method.invoke(base, (Object[]) null); } catch (Exception e) { Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e); ExceptionUtils.handleThrowable(thr); } } return value; } @Override public void setValue(ELContext context, Object base, Object property, Object value) { Objects.requireNonNull(context); if (base == null || property == null) { return; } Method method = getWriteMethod(base.getClass(), property.toString(), value.getClass()); if (method != null) { context.setPropertyResolved(base, property); try { method.invoke(base, value); } catch (Exception e) { Throwable thr = ExceptionUtils.unwrapInvocationTargetException(e); ExceptionUtils.handleThrowable(thr); } } } @Override public boolean isReadOnly(ELContext context, Object base, Object property) { Objects.requireNonNull(context); if (base == null || property == null) { return false; } Class<?> beanClass = base.getClass(); String prop = property.toString(); Method readMethod = getReadMethod(beanClass, prop); return readMethod == null || getWriteMethod(beanClass, prop, readMethod.getReturnType()) == null; } private static Method getReadMethod(Class<?> beanClass, String prop) { Method[] methods = beanClass.getMethods(); String isGetter = "is" + capitalize(prop); String getter = "get" + capitalize(prop); for (Method method : methods) { if (method.getParameterCount() == 0) { if (isGetter.equals(method.getName()) && method.getReturnType().equals(boolean.class)) { return method; } else if (getter.equals(method.getName())) { return method; } } } return null; } private static Method getWriteMethod(Class<?> beanClass, String prop, Class<?> valueClass) { String setter = "set" + capitalize(prop); Method[] methods = beanClass.getMethods(); for (Method method : methods) { if (method.getParameterCount() == 1 && setter.equals(method.getName()) && (valueClass == null || valueClass.isAssignableFrom(method.getParameterTypes()[0]))) { return method; } } return null; } private static String capitalize(String name) { if (name == null || name.isEmpty()) { return name; } char[] chars = name.toCharArray(); chars[0] = Character.toUpperCase(chars[0]); return new String(chars); } @Override public Class<?> getType(ELContext context, Object base, Object property) { return null; } @Override public Class<?> getCommonPropertyType(ELContext context, Object base) { if (base != null) { return Object.class; } return null; } } }
Detected license expression
apache-2.0
Detected license expression (SPDX)
Apache-2.0
Percentage of license text
12.45
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