Author: markt
Date: Sat Oct 27 19:44:52 2012
New Revision: 1402855

URL: http://svn.apache.org/viewvc?rev=1402855&view=rev
Log:
Use an optimised CompositeELResolver for Jasper that skips resolvers that are 
known to be unable to resolve the value.
Patch by Jarek Gawor.

Added:
    tomcat/trunk/java/org/apache/jasper/el/JasperELResolver.java   (with props)
Modified:
    tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java

Added: tomcat/trunk/java/org/apache/jasper/el/JasperELResolver.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/el/JasperELResolver.java?rev=1402855&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/el/JasperELResolver.java (added)
+++ tomcat/trunk/java/org/apache/jasper/el/JasperELResolver.java Sat Oct 27 
19:44:52 2012
@@ -0,0 +1,159 @@
+/*
+ * 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.util.List;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELContext;
+import javax.el.ELException;
+import javax.el.ELResolver;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.PropertyNotFoundException;
+import javax.el.ResourceBundleELResolver;
+import javax.servlet.jsp.el.ImplicitObjectELResolver;
+import javax.servlet.jsp.el.ScopedAttributeELResolver;
+
+/**
+ * Jasper-specific CompositeELResolver that optimizes certain functions to 
avoid
+ * unnecessary resolver calls.
+ */
+public class JasperELResolver extends CompositeELResolver {
+
+    private int size;
+    private ELResolver[] resolvers;
+    private int appResolversSize;
+
+    public JasperELResolver(List<ELResolver> appResolvers) {
+        appResolversSize = appResolvers.size();
+        resolvers = new ELResolver[0];
+        size = resolvers.length;
+
+        add(new ImplicitObjectELResolver());
+        for (ELResolver appResolver : appResolvers) {
+            add(appResolver);
+        }
+        add(new MapELResolver());
+        add(new ResourceBundleELResolver());
+        add(new ListELResolver());
+        add(new ArrayELResolver());
+        add(new BeanELResolver());
+        add(new ScopedAttributeELResolver());
+    }
+
+    @Override
+    public synchronized void add(ELResolver elResolver) {
+        super.add(elResolver);
+
+        ELResolver[] nr = new ELResolver[size + 1];
+        System.arraycopy(resolvers, 0, nr, 0, size);
+        nr[size] = elResolver;
+
+        resolvers = nr;
+        size ++;
+    }
+
+    @Override
+    public Object getValue(ELContext context, Object base, Object property)
+        throws NullPointerException, PropertyNotFoundException, ELException {
+        context.setPropertyResolved(false);
+
+        int start;
+        Object result = null;
+
+        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, base, property);
+                if (context.isPropertyResolved()) {
+                    return result;
+                }
+            }
+            // skip collection-based resolvers (map, resource, list, array, and
+            // bean)
+            start = index + 5;
+        } else {
+            // skip implicit resolver only
+            start = 1;
+        }
+
+        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.length() == 0) {
+            throw new ELException(new NoSuchMethodException());
+        }
+
+        context.setPropertyResolved(false);
+
+        Object result = null;
+
+        // skip implicit and call app resolvers
+        int index = 1 /* implicit */ + appResolversSize;
+        for (int i = 1; i < index; i++) {
+            result = resolvers[i].invoke(
+                    context, base, targetMethod, paramTypes, params);
+            if (context.isPropertyResolved()) {
+                return result;
+            }
+        }
+
+        // skip map, resource, list, and array resolvers
+        index += 4;
+        // call bean and the rest of resolvers
+        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 {@link org.apache.el.lang.ELSupport#coerceToString(Object)}.
+     */
+    private static final 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();
+        }
+    }
+}
\ No newline at end of file

Propchange: tomcat/trunk/java/org/apache/jasper/el/JasperELResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java?rev=1402855&r1=1402854&r2=1402855&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 
(original)
+++ tomcat/trunk/java/org/apache/jasper/runtime/JspApplicationContextImpl.java 
Sat Oct 27 19:44:52 2012
@@ -19,27 +19,20 @@ package org.apache.jasper.runtime;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
-import javax.el.ArrayELResolver;
-import javax.el.BeanELResolver;
 import javax.el.CompositeELResolver;
 import javax.el.ELContextEvent;
 import javax.el.ELContextListener;
 import javax.el.ELResolver;
 import javax.el.ExpressionFactory;
-import javax.el.ListELResolver;
-import javax.el.MapELResolver;
-import javax.el.ResourceBundleELResolver;
 import javax.servlet.ServletContext;
 import javax.servlet.jsp.JspApplicationContext;
 import javax.servlet.jsp.JspContext;
-import javax.servlet.jsp.el.ImplicitObjectELResolver;
-import javax.servlet.jsp.el.ScopedAttributeELResolver;
 
 import org.apache.jasper.Constants;
 import org.apache.jasper.el.ELContextImpl;
+import org.apache.jasper.el.JasperELResolver;
 
 /**
  * Implementation of JspApplicationContext
@@ -119,18 +112,7 @@ public class JspApplicationContextImpl i
     private ELResolver createELResolver() {
         this.instantiated = true;
         if (this.resolver == null) {
-            CompositeELResolver r = new CompositeELResolver();
-            r.add(new ImplicitObjectELResolver());
-            for (Iterator<ELResolver> itr = this.resolvers.iterator();
-                    itr.hasNext();) {
-                r.add(itr.next());
-            }
-            r.add(new MapELResolver());
-            r.add(new ResourceBundleELResolver());
-            r.add(new ListELResolver());
-            r.add(new ArrayELResolver());
-            r.add(new BeanELResolver());
-            r.add(new ScopedAttributeELResolver());
+            CompositeELResolver r = new JasperELResolver(this.resolvers);
             this.resolver = r;
         }
         return this.resolver;



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

Reply via email to