This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new 85ac6e44f8 Improve performance of scope lookups
85ac6e44f8 is described below
commit 85ac6e44f8ba188b859f19253ff39633d14cd300
Author: Mark Thomas <[email protected]>
AuthorDate: Thu Sep 21 15:11:02 2023 +0100
Improve performance of scope lookups
---
.../servlet/jsp/el/ImplicitObjectELResolver.java | 172 +++++++++++++--------
webapps/docs/changelog.xml | 9 ++
2 files changed, 115 insertions(+), 66 deletions(-)
diff --git a/java/javax/servlet/jsp/el/ImplicitObjectELResolver.java
b/java/javax/servlet/jsp/el/ImplicitObjectELResolver.java
index 24116e2aeb..47428a770f 100644
--- a/java/javax/servlet/jsp/el/ImplicitObjectELResolver.java
+++ b/java/javax/servlet/jsp/el/ImplicitObjectELResolver.java
@@ -19,9 +19,9 @@ package javax.servlet.jsp.el;
import java.beans.FeatureDescriptor;
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.Iterator;
import java.util.List;
@@ -45,31 +45,6 @@ import javax.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.
*/
@@ -82,35 +57,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;
@@ -122,8 +71,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);
}
}
@@ -135,8 +83,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();
}
@@ -148,8 +95,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;
}
@@ -159,14 +105,14 @@ public class ImplicitObjectELResolver extends ELResolver {
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext
context, Object base) {
- List<FeatureDescriptor> feats = new ArrayList<>(SCOPE_NAMES.length);
+ List<FeatureDescriptor> feats = new ArrayList<>(Scope.values().length);
FeatureDescriptor feat;
- for (String scopeName : SCOPE_NAMES) {
+ for (Scope scope : Scope.values()) {
feat = new FeatureDescriptor();
- feat.setDisplayName(scopeName);
+ feat.setDisplayName(scope.implicitName);
feat.setExpert(false);
feat.setHidden(false);
- feat.setName(scopeName);
+ feat.setName(scope.implicitName);
feat.setPreferred(true);
feat.setValue(RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
feat.setValue(TYPE, String.class);
@@ -183,6 +129,7 @@ public class ImplicitObjectELResolver extends ELResolver {
return null;
}
+
private static class ScopeManager {
private static final String MNGR_KEY = ScopeManager.class.getName();
@@ -473,6 +420,7 @@ public class ImplicitObjectELResolver extends ELResolver {
}
}
+
private abstract static class ScopeMap<V> extends AbstractMap<String,V> {
protected abstract Enumeration<String> getAttributeNames();
@@ -560,7 +508,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
@@ -596,4 +544,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 fccbeed32b..713ea813db 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: [email protected]
For additional commands, e-mail: [email protected]