2016-03-10 17:22 GMT+03:00  <ma...@apache.org>:
> Author: markt
> Date: Thu Mar 10 14:22:51 2016
> New Revision: 1734418
>
> URL: http://svn.apache.org/viewvc?rev=1734418&view=rev
> Log:
> Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=57583
> Improve long standing performance issue with EL and undefined attributes.
>
> Modified:
>     tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java
>     tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java
>     tomcat/trunk/webapps/docs/changelog.xml
>
> Modified: 
> tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java
> URL: 
> http://svn.apache.org/viewvc/tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java?rev=1734418&r1=1734417&r2=1734418&view=diff
> ==============================================================================
> --- tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java 
> (original)
> +++ tomcat/trunk/java/javax/servlet/jsp/el/ScopedAttributeELResolver.java Thu 
> Mar 10 14:22:51 2016
> @@ -35,6 +35,20 @@ import javax.servlet.jsp.PageContext;
>  */
>  public class ScopedAttributeELResolver extends ELResolver {
>
> +    // Indicates if a performance short-cut is available
> +    private static final Class<?> AST_IDENTIFIER_KEY;
> +
> +    static {
> +        Class<?> key = null;
> +        try {
> +            key = Class.forName("org.apache.el.parser.AstIdentifier");
> +        } catch (Exception e) {
> +            // Ignore: Expected if not running on Tomcat. Not a problem since
> +            //         this just allows a short-cut.
> +        }
> +        AST_IDENTIFIER_KEY = key;
> +    }
> +
>      @Override
>      public Object getValue(ELContext context, Object base, Object property) {
>          if (context == null) {
> @@ -51,10 +65,26 @@ public class ScopedAttributeELResolver e
>                  result = page.findAttribute(key);
>
>                  if (result == null) {
> +                    boolean resolveClass = true;
> +                    // Performance short-cut available when running on Tomcat
> +                    if (AST_IDENTIFIER_KEY != null) {
> +                        // Tomcat will set this key to Boolean.TRUE if the
> +                        // identifier is a stand-alone identifier (i.e.
> +                        // identifier) rather than part of an AstValue (i.e.
> +                        // identifier.something). Imports do not need to be
> +                        // checked if this is a stand-alone identifier
> +                        Boolean value = (Boolean) 
> context.getContext(AST_IDENTIFIER_KEY);
> +                        if (value != null && value.booleanValue()) {
> +                            resolveClass = false;
> +                        }
> +                    }
>                      // This might be the name of an imported class
>                      ImportHandler importHandler = context.getImportHandler();
>                      if (importHandler != null) {
> -                        Class<?> clazz = importHandler.resolveClass(key);
> +                        Class<?> clazz = null;
> +                        if (resolveClass) {
> +                            clazz = importHandler.resolveClass(key);
> +                        }
>                          if (clazz != null) {
>                              result = new ELClass(clazz);
>                          }
>
> Modified: tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java
> URL: 
> http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java?rev=1734418&r1=1734417&r2=1734418&view=diff
> ==============================================================================
> --- tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java (original)
> +++ tomcat/trunk/java/org/apache/el/parser/AstIdentifier.java Thu Mar 10 
> 14:22:51 2016
> @@ -77,7 +77,27 @@ public final class AstIdentifier extends
>
>          // EL Resolvers
>          ctx.setPropertyResolved(false);
> -        Object result = ctx.getELResolver().getValue(ctx, null, this.image);
> +        Object result;
> +        /* Putting the Boolean into the ELContext is part of a performance
> +         * optimisation for ScopedAttributeELResolver. When looking up "foo",
> +         * the resolver can't differentiate between ${ foo } and ${ foo.bar 
> }.
> +         * This is important because the expensive class lookup only needs to
> +         * be performed in the later case. This flag tells the resolver if 
> the
> +         * lookup can be skipped.
> +         */
> +        if (parent instanceof AstValue) {
> +            ctx.putContext(this.getClass(), Boolean.FALSE);
> +        } else {
> +            ctx.putContext(this.getClass(), Boolean.TRUE);
> +        }

Honestly, I do not understand the above if/else block.

I do not see how the difference of "${ foo } vs ${ foo.bar }" maps
into "(parent instanceof AstValue)" check.

What is the meaning of "parent" in Ast?
What possible values can it have?

Does this handle method calls, such as ${System.currentTimeMillis()}  ?

> +        try {
> +            result = ctx.getELResolver().getValue(ctx, null, this.image);
> +        } finally {
> +            // Always reset the flag to false so the optimisation is not 
> applied
> +            // inappropriately
> +            ctx.putContext(this.getClass(), Boolean.FALSE);
> +        }
> +
>          if (ctx.isPropertyResolved()) {
>              return result;
>          }

Below these lines the AstIdentifier does its own
ImportHandler.resolveClass(), resolveStatic() calls.

This duplicates the work performed by ScopedAttributeELResolver and I
wonder whether it is necessary.

Those lines originate from
http://svn.apache.org/viewvc?diff_format=l&view=revision&revision=1504286


> Modified: tomcat/trunk/webapps/docs/changelog.xml
> URL: 
> http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1734418&r1=1734417&r2=1734418&view=diff
> ==============================================================================
> --- tomcat/trunk/webapps/docs/changelog.xml (original)
> +++ tomcat/trunk/webapps/docs/changelog.xml Thu Mar 10 14:22:51 2016
> @@ -222,6 +222,12 @@
>        <update>
>          Update to the Eclipse JDT Compiler 4.5.1. (markt)
>        </update>
> +      <fix>
> +        <bug>57583</bug>: Improve the performance of
> +        <code>javax.servlet.jsp.el.ScopedAttributeELResolver</code> when
> +        resolving attributes that do not exist. This improvement only works 
> when
> +        Jasper is used with with Tomcat's EL implementation. (markt)
> +      </fix>
>      </changelog>
>    </subsection>
>    <subsection name="WebSocket">
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
> For additional commands, e-mail: dev-h...@tomcat.apache.org
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to