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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org