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 79a0e29a61 Fix BZ 68119 - Refactor for improved performance during
type conversion
79a0e29a61 is described below
commit 79a0e29a611d582135ebfb3740c060363c13f877
Author: Mark Thomas <[email protected]>
AuthorDate: Mon Nov 27 14:01:49 2023 +0000
Fix BZ 68119 - Refactor for improved performance during type conversion
https://bz.apache.org/bugzilla/show_bug.cgi?id=68119
---
java/jakarta/el/CompositeELResolver.java | 49 ++++++++++++++++++++++++++++++--
webapps/docs/changelog.xml | 8 ++++++
2 files changed, 55 insertions(+), 2 deletions(-)
diff --git a/java/jakarta/el/CompositeELResolver.java
b/java/jakarta/el/CompositeELResolver.java
index 5c931dfe05..f8050c5809 100644
--- a/java/jakarta/el/CompositeELResolver.java
+++ b/java/jakarta/el/CompositeELResolver.java
@@ -16,11 +16,14 @@
*/
package jakarta.el;
+import java.util.HashSet;
import java.util.Objects;
+import java.util.Set;
public class CompositeELResolver extends ELResolver {
private static final Class<?> SCOPED_ATTRIBUTE_EL_RESOLVER;
+ private static final Set<String> KNOWN_NON_TYPE_CONVERTING_RESOLVERS = new
HashSet<>();
static {
Class<?> clazz = null;
try {
@@ -29,15 +32,43 @@ public class CompositeELResolver extends ELResolver {
// Ignore. This is expected if using the EL stand-alone
}
SCOPED_ATTRIBUTE_EL_RESOLVER = clazz;
+
+ // EL API Resolvers
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(ArrayELResolver.class.getName());
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(BeanELResolver.class.getName());
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(BeanNameELResolver.class.getName());
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(ListELResolver.class.getName());
+ KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(MapELResolver.class.getName());
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(OptionalELResolver.class.getName());
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(RecordELResolver.class.getName());
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(ResourceBundleELResolver.class.getName());
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add(StaticFieldELResolver.class.getName());
+ // JSP API Resolvers - referenced by name to avoid creating dependency
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.ImplicitObjectELResolver");
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.ImportELResolver");
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.NotFoundELResolver");
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("jakarta.servlet.jsp.el.ScopedAttributeELResolver");
+ // Tomcat internal resolvers - referenced by name to avoid creating
dependency
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("org.apache.jasper.el.JasperELResolver");
+
KNOWN_NON_TYPE_CONVERTING_RESOLVERS.add("org.apache.el.stream.StreamELResolverImpl");
}
private int resolversSize;
-
private ELResolver[] resolvers;
+ /*
+ * Use a separate array for ELResolvers that might implement type
conversion as a performance optimisation. See
+ * https://bz.apache.org/bugzilla/show_bug.cgi?id=68119
+ */
+ private int typeConvertersSize;
+ private ELResolver[] typeConverters;
+
public CompositeELResolver() {
resolversSize = 0;
resolvers = new ELResolver[8];
+
+ typeConvertersSize = 0;
+ typeConverters = new ELResolver[0];
}
public void add(ELResolver elResolver) {
@@ -53,6 +84,20 @@ public class CompositeELResolver extends ELResolver {
resolvers = nr;
}
resolvers[resolversSize++] = elResolver;
+
+ if
(KNOWN_NON_TYPE_CONVERTING_RESOLVERS.contains(elResolver.getClass().getName()))
{
+ // Performance optimisation. ELResolver known not to perform type
conversion
+ return;
+ }
+
+ if (typeConvertersSize == 0) {
+ typeConverters = new ELResolver[1];
+ } else if (typeConvertersSize == typeConverters.length) {
+ ELResolver[] expandedTypeConverters = new
ELResolver[typeConvertersSize * 2];
+ System.arraycopy(typeConverters, 0, expandedTypeConverters, 0,
typeConvertersSize);
+ typeConverters = expandedTypeConverters;
+ }
+ typeConverters[typeConvertersSize++] = elResolver;
}
@Override
@@ -145,7 +190,7 @@ public class CompositeELResolver extends ELResolver {
@Override
public <T> T convertToType(ELContext context, Object obj, Class<T> type) {
context.setPropertyResolved(false);
- int sz = this.resolversSize;
+ int sz = typeConvertersSize;
for (int i = 0; i < sz; i++) {
T result = this.resolvers[i].convertToType(context, obj, type);
if (context.isPropertyResolved()) {
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index e4f507a131..4099b3aa04 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -132,6 +132,14 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Jasper">
+ <changelog>
+ <scode>
+ <bug>68119</bug>: Refactor the <code>CompositeELResolver</code> to
+ improve performance during type conversion operations. (markt)
+ </scode>
+ </changelog>
+ </subsection>
<subsection name="Other">
<changelog>
<update>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]