You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by kk...@apache.org on 2014/06/11 17:23:25 UTC

svn commit: r1601924 - in /tomcat/trunk: java/org/apache/jasper/compiler/JspReader.java java/org/apache/jasper/compiler/Parser.java webapps/docs/changelog.xml

Author: kkolinko
Date: Wed Jun 11 15:23:25 2014
New Revision: 1601924

URL: http://svn.apache.org/r1601924
Log:
Move code that parses EL expressions within JSP template text from Parser to JspReader class.
This is done to get access to JspReader.nextChar(mark) to avoid calling reader.mark() in a loop, as that method allocates new Mark object on each call.

Also removed duplicate "start = reader.mark();" call, as parseELExpression() does update 'start'.

Modified:
    tomcat/trunk/java/org/apache/jasper/compiler/JspReader.java
    tomcat/trunk/java/org/apache/jasper/compiler/Parser.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/jasper/compiler/JspReader.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/JspReader.java?rev=1601924&r1=1601923&r2=1601924&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/JspReader.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/JspReader.java Wed Jun 11 15:23:25 2014
@@ -484,6 +484,58 @@ class JspReader {
         return ret;
     }
 
+    /**
+     * Parse ELExpressionBody that is a body of ${} or #{} expression. Initial
+     * reader position is expected to be just after '${' or '#{' characters.
+     * <p>
+     * In case of success, this method returns <code>Mark</code> for the last
+     * character before the terminating '}' and reader is positioned just after
+     * the '}' character. If no terminating '}' is encountered, this method
+     * returns <code>null</code>.
+     * <p>
+     * Starting with EL 3.0, nested paired {}s are supported.
+     *
+     * @return Mark for the last character of EL expression or <code>null</code>
+     */
+    Mark skipELExpression() throws JasperException {
+        // ELExpressionBody.
+        //  Starts with "#{" or "${".  Ends with "}".
+        //  May contain quoted "{", "}", '{', or '}' and nested "{...}"
+        Mark last = mark();
+        boolean singleQuoted = false;
+        boolean doubleQuoted = false;
+        int nesting = 0;
+        int currentChar;
+        do {
+            currentChar = nextChar(last);
+            while (currentChar == '\\' && (singleQuoted || doubleQuoted)) {
+                // skip character following '\' within quotes
+                // No need to update 'last', as neither of these characters
+                // can be the closing '}'.
+                nextChar();
+                currentChar = nextChar();
+            }
+            if (currentChar == -1) {
+                return null;
+            }
+            if (currentChar == '"' && !singleQuoted) {
+                doubleQuoted = !doubleQuoted;
+            } else if (currentChar == '\'' && !doubleQuoted) {
+                singleQuoted = !singleQuoted;
+            } else if (currentChar == '{' && !doubleQuoted && !singleQuoted) {
+                nesting++;
+            } else if (currentChar =='}' && !doubleQuoted && !singleQuoted) {
+                // Note: This also matches the terminating '}' at which point
+                //       nesting will be set to -1 - hence the test for
+                //       while (currentChar != '}' || nesting > -1 ||...) below
+                //       to continue the loop until the final '}' is detected
+                nesting--;
+            }
+        } while (currentChar != '}' || singleQuoted || doubleQuoted || nesting > -1);
+
+        return last;
+    }
+
     final boolean isSpace() throws JasperException {
         // Note: If this logic changes, also update Node.TemplateText.rtrim()
         return peekChar() <= ' ';

Modified: tomcat/trunk/java/org/apache/jasper/compiler/Parser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/jasper/compiler/Parser.java?rev=1601924&r1=1601923&r2=1601924&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/jasper/compiler/Parser.java (original)
+++ tomcat/trunk/java/org/apache/jasper/compiler/Parser.java Wed Jun 11 15:23:25 2014
@@ -736,46 +736,20 @@ class Parser implements TagConstants {
     }
 
     /*
-     * ELExpressionBody. Starts with "#{" or "${".  Ends with "}".May contain
-     *                   quoted "{", "}", '{', or '}' and nested "{...}"
+     * ELExpressionBody. Starts with "#{" or "${".  Ends with "}".
+     * See JspReader.skipELExpression().
      */
     private void parseELExpression(Node parent, char type)
             throws JasperException {
         start = reader.mark();
-        Mark last = null;
-        boolean singleQuoted = false;
-        boolean doubleQuoted = false;
-        int nesting = 0;
-        int currentChar;
-        do {
-            // XXX could move this logic to JspReader
-            last = reader.mark(); // XXX somewhat wasteful
-            currentChar = reader.nextChar();
-            while (currentChar == '\\' && (singleQuoted || doubleQuoted)) {
-                // skip character following '\' within quotes
-                reader.nextChar();
-                currentChar = reader.nextChar();
-            }
-            if (currentChar == -1)
-                err.jspError(start, "jsp.error.unterminated", type + "{");
-            if (currentChar == '"' && !singleQuoted) {
-                doubleQuoted = !doubleQuoted;
-            } else if (currentChar == '\'' && !doubleQuoted) {
-                singleQuoted = !singleQuoted;
-            } else if (currentChar == '{' && !doubleQuoted && !singleQuoted) {
-                nesting++;
-            } else if (currentChar =='}' && !doubleQuoted && !singleQuoted) {
-                // Note: This also matches the terminating '}' at which point
-                //       nesting will be set to -1 - hence the test for
-                //       while (currentChar != '}' || nesting > -1 ||...) below
-                //       to continue the loop until the final '}' is detected
-                nesting--;
-            }
-        } while (currentChar != '}' || singleQuoted || doubleQuoted || nesting > -1);
+        Mark last = reader.skipELExpression();
+        if (last == null) {
+            err.jspError(start, "jsp.error.unterminated", type + "{");
+        }
 
         @SuppressWarnings("unused")
-        Node unused = new Node.ELExpression(
-                type, reader.getText(start, last), start, parent);
+        Node unused = new Node.ELExpression(type, reader.getText(start, last),
+                start, parent);
     }
 
     /*
@@ -1408,7 +1382,6 @@ class Parser implements TagConstants {
                             ttext.toString(), start, parent);
 
                     // Mark and parse the EL expression and create its node:
-                    start = reader.mark();
                     parseELExpression(parent, (char) ch);
 
                     start = reader.mark();

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1601924&r1=1601923&r2=1601924&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Wed Jun 11 15:23:25 2014
@@ -217,6 +217,11 @@
         <bug>56612</bug>: Correctly parse two consecutive escaped single quotes
         when used in UEL expression in a JSP. (markt)
       </fix>
+      <update>
+        Move code that parses EL expressions within JSP template text from
+        <code>Parser</code> to <code>JspReader</code> class for better
+        performance. (kkolinko)
+      </update>
     </changelog>
   </subsection>
   <subsection name="WebSocket">



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