remm 02/04/30 01:15:58 Modified: jasper2/src/share/org/apache/jasper/compiler Generator.java Log: - Apply patch to fix bug 8290. - The only drawback I can see is that it creates a Vector and a BitSet even if the page does not use tags. It seems acceptable, though. - Passes Watchdog and runs the TC admin webapp :) - The code generated implements the same flow as with nested try/catch/finally blocks. - The administration webapp in Tomcat, which felt sluggish before, now feels snappy, so I don't need any fancy graphs to see a nice performance difference :) - This patch should be reviewed by Jasper gurus. - Patch submitted by Denis Benoit <denoitde at sympatico.ca> Revision Changes Path 1.7 +164 -24 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java Index: Generator.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- Generator.java 25 Apr 2002 18:16:06 -0000 1.6 +++ Generator.java 30 Apr 2002 08:15:58 -0000 1.7 @@ -1,7 +1,7 @@ /* - * $Header: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v 1.6 2002/04/25 18:16:06 kinman Exp $ - * $Revision: 1.6 $ - * $Date: 2002/04/25 18:16:06 $ + * $Header: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Generator.java,v 1.7 2002/04/30 08:15:58 remm Exp $ + * $Revision: 1.7 $ + * $Date: 2002/04/30 08:15:58 $ * * ==================================================================== * @@ -63,6 +63,8 @@ import java.util.*; import java.beans.*; import java.net.URLEncoder; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; import java.lang.reflect.Method; import javax.servlet.jsp.tagext.*; import org.xml.sax.Attributes; @@ -91,6 +93,9 @@ private JspCompilationContext ctxt; private boolean breakAtLF; private PageInfo pageInfo; + private FinallyApplyer finallies; + private int tryBit; + private Stack tryStack; /** * @param s the input string @@ -199,6 +204,17 @@ // Constructor (empty so far) here // Other methods here + out.printil("private void addTagToVector(java.util.Vector tags, int index, javax.servlet.jsp.tagext.Tag tag) {"); + out.pushIndent(); + out.printil("if (index + 1 > tags.size())"); + out.pushIndent(); + out.printil("tags.setSize(index + 1);"); + out.popIndent(); + out.printil("tags.setElementAt(tag, index);"); + out.popIndent(); + out.printil("}"); + out.println(); + out.println(); // Now the service method out.printin("public void "); @@ -222,6 +238,8 @@ out.printil("ServletConfig config = null;"); out.printil("JspWriter out = null;"); out.printil("Object page = this;"); + out.printil("java.util.BitSet bitmask = new java.util.BitSet();"); + out.printil("java.util.Vector tags = new java.util.Vector();"); out.printil("try {"); out.pushIndent(); @@ -882,6 +900,10 @@ out.println(" ---- */"); Class tagHandlerClass = handlerInfo.getTagHandlerClass(); + + boolean implementsTryCatchFinally = + TryCatchFinally.class.isAssignableFrom(tagHandlerClass); + out.printin(tagHandlerClass.getName()); out.print(" "); out.print(tagHandlerVar); @@ -895,8 +917,22 @@ declareTagVariableInfos(tagVarInfos, n.getTagData(), VariableInfo.AT_BEGIN); - out.printil("try {"); - out.pushIndent(); + if (implementsTryCatchFinally) { + out.printil("try {"); + out.pushIndent(); + } else { + out.printil("// try {"); + out.printin("bitmask.set("); + Integer tryBitVal = new Integer(tryBit++); + tryStack.push(tryBitVal); + out.print(tryBitVal.toString()); + out.println(");"); + out.printin("addTagToVector(tags, "); + out.print(tryBitVal.toString()); + out.print(", "); + out.print(tagHandlerVar); + out.println(");"); + } out.printin("int "); out.print(tagEvalVar); out.print(" = "); @@ -918,8 +954,17 @@ out.pushIndent(); if (isBodyTag) { - out.printil("try {"); - out.pushIndent(); + out.printil("// try {"); + out.printin("bitmask.set("); + Integer tryBitVal = new Integer(tryBit++); + tryStack.push(tryBitVal); + out.print(tryBitVal.toString()); + out.println(");"); + out.printin("addTagToVector(tags, "); + out.print(tryBitVal.toString()); + out.print(", "); + out.print(tagHandlerVar); + out.println(");"); out.printin("if ("); out.print(tagEvalVar); out.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE) {"); @@ -981,21 +1026,37 @@ if (n.getBody() != null) { if (implementsBodyTag) { - out.popIndent(); // try + Integer tryBitVal = (Integer)tryStack.pop(); + out.printil("// } finally {"); + out.printin("bitmask.clear("); + out.print(tryBitVal.toString()); + out.println(");"); + + out.printin("addTagToVector(tags, "); + out.print(tryBitVal.toString()); + out.print(", "); + out.print(tagHandlerVar); + out.println(");"); - out.printil("} finally {"); - out.pushIndent(); out.printin("if ("); out.print(tagEvalVar); out.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)"); out.pushIndent(); out.printil("out = pageContext.popBody();"); out.popIndent(); - - out.popIndent(); - out.printil("}"); + + finallies.beginPartMethod(tryBitVal.intValue()); + finallies.print(" if ("); + finallies.print("((javax.servlet.jsp.tagext.BodyTag)tags.elementAt("); + finallies.print(tryBitVal.toString()); + finallies.print(")).doAfterBody()"); + finallies.println(" != javax.servlet.jsp.tagext.Tag.EVAL_BODY_INCLUDE)"); + finallies.println(" out = pageContext.popBody();"); + + finallies.endPartMethod(); + out.printil("// }"); } - + out.popIndent(); // EVAL_BODY out.printil("}"); } @@ -1007,26 +1068,38 @@ out.printil("return;"); out.popIndent(); - out.popIndent(); // try - // TryCatchFinally if (implementsTryCatchFinally) { + out.popIndent(); // try out.printil("} catch (Throwable _jspx_exception) {"); out.pushIndent(); out.printin(tagHandlerVar); out.println(".doCatch(_jspx_exception);"); out.popIndent(); - } - out.printil("} finally {"); - out.pushIndent(); - if (implementsTryCatchFinally) { + out.printil("} finally {"); + out.pushIndent(); out.printin(tagHandlerVar); out.println(".doFinally();"); + out.printin(tagHandlerVar); + out.println(".release();"); + out.popIndent(); + out.printil("}"); + } else { + Integer tryBitVal = (Integer)tryStack.pop(); + out.printil("// } finally {"); + out.printin("bitmask.clear("); + out.print(tryBitVal.toString()); + out.println(");"); + out.printin(tagHandlerVar); + out.println(".release();"); + out.printil("// }"); + finallies.beginPartMethod(tryBitVal.intValue()); + finallies.printin("((javax.servlet.jsp.tagext.Tag)tags.elementAt("); + finallies.print(tryBitVal.toString()); + finallies.print("))"); + finallies.println(".release();"); + finallies.endPartMethod(); } - out.printin(tagHandlerVar); - out.println(".release();"); - out.popIndent(); - out.printil("}"); // Declare and update AT_END variables updateVariableInfos(varInfos, VariableInfo.AT_END, true); @@ -1302,7 +1375,18 @@ out.pushIndent(); // Do stuff here for finally actions... + + out.printil("try {"); + out.pushIndent(); + out.printil("finallies(bitmask, out, tags, pageContext);"); + out.popIndent(); + out.printil("} catch (javax.servlet.jsp.JspException e) {"); + out.pushIndent(); + out.printil("if (pageContext != null) pageContext.handlePageException(e);"); + out.popIndent(); + out.printil("}"); out.printil("if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);"); + out.popIndent(); out.printil("}"); @@ -1310,6 +1394,10 @@ out.popIndent(); out.printil("}"); + // Call the final method + finallies.done(); + out.printil(finallies.toString()); + // Close the class definition out.popIndent(); out.printil("}"); @@ -1325,6 +1413,8 @@ pageInfo = compiler.getPageInfo(); beanInfo = pageInfo.getBeanRepository(); breakAtLF = ctxt.getOptions().getMappedFile(); + finallies = new FinallyApplyer(); + tryStack = new Stack(); } /** @@ -1419,5 +1509,55 @@ return tagHandlerClass; } } + + private static class FinallyApplyer { + private PrintStream finalOutput; + private ByteArrayOutputStream rawOutput; + + FinallyApplyer() { + rawOutput = new ByteArrayOutputStream(); + finalOutput = new PrintStream(rawOutput, true); + + finalOutput.println(); + finalOutput.println(" private void finallies(java.util.BitSet bitmask, JspWriter out, java.util.Vector tags, PageContext pageContext)"); + finalOutput.println(" throws javax.servlet.jsp.JspException {"); + } + + public void done() { + finalOutput.println(" }"); + } + + public void beginPartMethod(int bit) { + finalOutput.print(" if (bitmask.get("); + finalOutput.print(bit); + finalOutput.println(")) {"); + } + + public void endPartMethod() { + finalOutput.println(" }"); + finalOutput.println(); + } + + public void println(String aLine) { + if (null != aLine) { + finalOutput.print(aLine); + } + finalOutput.println(); + } + + public void printin(String partLine) { + finalOutput.print(" "); + finalOutput.print(partLine); + } + + public void print(String partLine) { + finalOutput.print(partLine); + } + + public String toString() { + return rawOutput.toString(); + } + } + }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>