This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/main by this push: new d5587f0463 Improve performance of scope lookups d5587f0463 is described below commit d5587f0463745325be913a9ba15f7f01f0b48a6c Author: Mark Thomas <ma...@apache.org> AuthorDate: Thu Sep 21 15:11:02 2023 +0100 Improve performance of scope lookups --- .../servlet/jsp/el/ImplicitObjectELResolver.java | 164 +++++++++++++-------- webapps/docs/changelog.xml | 9 ++ 2 files changed, 111 insertions(+), 62 deletions(-) diff --git a/java/jakarta/servlet/jsp/el/ImplicitObjectELResolver.java b/java/jakarta/servlet/jsp/el/ImplicitObjectELResolver.java index 1e4b5f87cd..cbcf446ca3 100644 --- a/java/jakarta/servlet/jsp/el/ImplicitObjectELResolver.java +++ b/java/jakarta/servlet/jsp/el/ImplicitObjectELResolver.java @@ -18,9 +18,9 @@ package jakarta.servlet.jsp.el; import java.util.AbstractMap; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -43,31 +43,6 @@ import jakarta.servlet.jsp.PageContext; */ public class ImplicitObjectELResolver extends ELResolver { - private static final String[] SCOPE_NAMES = new String[] { "applicationScope", "cookie", "header", "headerValues", - "initParam", "pageContext", "pageScope", "param", "paramValues", "requestScope", "sessionScope" }; - - private static final int APPLICATIONSCOPE = 0; - - private static final int COOKIE = 1; - - private static final int HEADER = 2; - - private static final int HEADERVALUES = 3; - - private static final int INITPARAM = 4; - - private static final int PAGECONTEXT = 5; - - private static final int PAGESCOPE = 6; - - private static final int PARAM = 7; - - private static final int PARAM_VALUES = 8; - - private static final int REQUEST_SCOPE = 9; - - private static final int SESSION_SCOPE = 10; - /** * Creates an instance of the implicit object resolver for EL. */ @@ -80,35 +55,9 @@ public class ImplicitObjectELResolver extends ELResolver { Objects.requireNonNull(context); if (base == null && property != null) { - int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString()); - - if (idx >= 0) { - PageContext page = (PageContext) context.getContext(JspContext.class); - context.setPropertyResolved(base, property); - switch (idx) { - case APPLICATIONSCOPE: - return ScopeManager.get(page).getApplicationScope(); - case COOKIE: - return ScopeManager.get(page).getCookie(); - case HEADER: - return ScopeManager.get(page).getHeader(); - case HEADERVALUES: - return ScopeManager.get(page).getHeaderValues(); - case INITPARAM: - return ScopeManager.get(page).getInitParam(); - case PAGECONTEXT: - return ScopeManager.get(page).getPageContext(); - case PAGESCOPE: - return ScopeManager.get(page).getPageScope(); - case PARAM: - return ScopeManager.get(page).getParam(); - case PARAM_VALUES: - return ScopeManager.get(page).getParamValues(); - case REQUEST_SCOPE: - return ScopeManager.get(page).getRequestScope(); - case SESSION_SCOPE: - return ScopeManager.get(page).getSessionScope(); - } + Scope scope = Scope.lookupMap.get(property.toString()); + if (scope != null) { + return scope.getScopeValue(context, base, property); } } return null; @@ -119,8 +68,7 @@ public class ImplicitObjectELResolver extends ELResolver { Objects.requireNonNull(context); if (base == null && property != null) { - int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString()); - if (idx >= 0) { + if (Scope.lookupMap.containsKey(property.toString())) { context.setPropertyResolved(base, property); } } @@ -132,8 +80,7 @@ public class ImplicitObjectELResolver extends ELResolver { Objects.requireNonNull(context); if (base == null && property != null) { - int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString()); - if (idx >= 0) { + if (Scope.lookupMap.containsKey(property.toString())) { context.setPropertyResolved(base, property); throw new PropertyNotWritableException(); } @@ -145,8 +92,7 @@ public class ImplicitObjectELResolver extends ELResolver { Objects.requireNonNull(context); if (base == null && property != null) { - int idx = Arrays.binarySearch(SCOPE_NAMES, property.toString()); - if (idx >= 0) { + if (Scope.lookupMap.containsKey(property.toString())) { context.setPropertyResolved(base, property); return true; } @@ -162,6 +108,7 @@ public class ImplicitObjectELResolver extends ELResolver { return null; } + private static class ScopeManager { private static final String MNGR_KEY = ScopeManager.class.getName(); @@ -452,6 +399,7 @@ public class ImplicitObjectELResolver extends ELResolver { } } + private abstract static class ScopeMap<V> extends AbstractMap<String,V> { protected abstract Enumeration<String> getAttributeNames(); @@ -539,7 +487,7 @@ public class ImplicitObjectELResolver extends ELResolver { @Override public boolean equals(Object obj) { - return (obj != null && this.hashCode() == obj.hashCode()); + return obj != null && this.hashCode() == obj.hashCode(); } @Override @@ -575,4 +523,96 @@ public class ImplicitObjectELResolver extends ELResolver { return null; } } + + + private enum Scope { + APPLICATION_SCOPE("applicationScope") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getApplicationScope(); + } + }, + COOKIE("cookie") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getCookie(); + } + }, + HEADER("header") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getHeader(); + } + }, + HEADER_VALUES("headerValues") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getHeaderValues(); + } + }, + INIT_PARAM("initParam") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getInitParam(); + } + }, + PAGE_CONTEXT("pageContext") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getPageContext(); + } + }, + PAGE_SCOPE("pageScope") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getPageScope(); + } + }, + PARAM("param") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getParam(); + } + }, + PARAM_VALUES("paramValues") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getParamValues(); + } + }, + REQUEST_SCOPE("requestScope") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getRequestScope(); + } + }, + SESSION_SCOPE("sessionScope") { + @Override + Object getScopeValue(ELContext context, Object base, Object property) { + return getScopeManager(context, base, property).getSessionScope(); + } + }; + + private static final Map<String,Scope> lookupMap = new HashMap<>(); + + static { + for (Scope scope : Scope.values()) { + lookupMap.put(scope.implicitName, scope); + } + } + + private static ScopeManager getScopeManager(ELContext context, Object base, Object property) { + PageContext page = (PageContext) context.getContext(JspContext.class); + context.setPropertyResolved(base, property); + return ScopeManager.get(page); + } + + private final String implicitName; + + Scope(String implicitName) { + this.implicitName = implicitName; + } + + abstract Object getScopeValue(ELContext context, Object base, Object property); + } } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 2d223df227..f9d35fc487 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -142,6 +142,15 @@ </fix> </changelog> </subsection> + <subsection name="Jasper"> + <changelog> + <fix> + <bug>67080</bug>: Improve performance of EL expressions in JSPs that use + implicit objects. Based on suggestions by John Engebretson, Anurag Dubey + and Christopher Schultz. (markt) + </fix> + </changelog> + </subsection> <subsection name="Other"> <changelog> <update> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org