kinman 2004/03/08 13:28:30 Modified: jasper2/src/share/org/apache/jasper/compiler Compiler.java Generator.java Node.java SmapUtil.java Log: - Currently, smap for inner classes are not generated to the correct class files. For inner class defined in servlet codes, there is nothing Jasper can do, since the servlet codes are not parsed. However, for inner classes generated by Jasper, such as the helper classes for handling fragments, the following changes are made to fix this problem: - Add a field in Node to indicate the name of a inner class. This field is set in Generator, and accessed in SmapUtil. - In SmapUtil.generateSamp(), when scanning the page nodes, if the codes are meant for a inner class, the smap is generated to a buffer. It now returns an array, pairing the class file names with their corresponding smaps. - SmapUtil.installSmap() takes the array as an augment, and install the smaps into the corresponding class files. Revision Changes Path 1.78 +5 -5 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java Index: Compiler.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Compiler.java,v retrieving revision 1.77 retrieving revision 1.78 diff -u -r1.77 -r1.78 --- Compiler.java 23 Jan 2004 01:50:08 -0000 1.77 +++ Compiler.java 8 Mar 2004 21:28:28 -0000 1.78 @@ -186,10 +186,10 @@ * @return a smap for the current JSP page, if one is generated, * null otherwise */ - private String generateJava() + private String[] generateJava() throws Exception { - String smapStr = null; + String[] smapStr = null; long t1=System.currentTimeMillis(); @@ -306,7 +306,7 @@ /** * Compile the servlet from .java file to .class file */ - private void generateClass(String smap) + private void generateClass(String[] smap) throws FileNotFoundException, JasperException, Exception { long t1=System.currentTimeMillis(); @@ -426,7 +426,7 @@ // JSR45 Support if (! options.isSmapSuppressed()) { - SmapUtil.installSmap(ctxt.getClassFileName(), smap); + SmapUtil.installSmap(smap); } } @@ -453,7 +453,7 @@ } try { - String smap = generateJava(); + String[] smap = generateJava(); if (compileClass) { generateClass(smap); } 1.223 +6 -3 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.222 retrieving revision 1.223 diff -u -r1.222 -r1.223 --- Generator.java 2 Mar 2004 19:39:12 -0000 1.222 +++ Generator.java 8 Mar 2004 21:28:28 -0000 1.223 @@ -94,6 +94,8 @@ * @author Mandar Raje * @author Rajiv Mordani * @author Pierre Delisle + * + * Tomcat 4.1.x and Tomcat 5: * @author Kin-man Chung * @author Jan Luehe * @author Shawn Bayern @@ -3913,6 +3915,7 @@ Fragment result = new Fragment(fragments.size(), parent); fragments.add(result); this.used = true; + parent.setInnerClassName(className); ServletWriter out = result.getGenBuffer().getOut(); out.pushIndent(); 1.80 +18 -3 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java Index: Node.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/Node.java,v retrieving revision 1.79 retrieving revision 1.80 diff -u -r1.79 -r1.80 --- Node.java 1 Mar 2004 22:51:34 -0000 1.79 +++ Node.java 8 Mar 2004 21:28:29 -0000 1.80 @@ -116,6 +116,13 @@ protected Nodes namedAttributeNodes; // cached for performance protected String qName; protected String localName; + /* + * The name of the inner class to which the codes for this node and + * its body are generated. For instance, for <jsp:body> in foo.jsp, + * this is "foo_jspHelper". This is primarily used for communicating + * such info from Generator to Smap generator. + */ + protected String innerClassName; private boolean isDummy; @@ -398,6 +405,14 @@ n = n.getParent(); } return (Node.Root) n; + } + + public String getInnerClassName() { + return innerClassName; + } + + public void setInnerClassName(String icn) { + innerClassName = icn; } /** 1.22 +90 -10 jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/SmapUtil.java Index: SmapUtil.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-jasper/jasper2/src/share/org/apache/jasper/compiler/SmapUtil.java,v retrieving revision 1.21 retrieving revision 1.22 diff -u -r1.21 -r1.22 --- SmapUtil.java 9 Dec 2003 02:51:35 -0000 1.21 +++ SmapUtil.java 8 Mar 2004 21:28:29 -0000 1.22 @@ -65,6 +65,9 @@ import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; import org.apache.jasper.JasperException; import org.apache.jasper.JspCompilationContext; @@ -99,13 +102,22 @@ * @param pageNodes The current JSP page * @return a SMAP for the page */ - public static String generateSmap( + public static String[] generateSmap( JspCompilationContext ctxt, Node.Nodes pageNodes) throws IOException { + + // Scan the nodes for presence of Jasper generated inner classes + PreScanVisitor psVisitor = new PreScanVisitor(); + try { + pageNodes.visit(psVisitor); + } catch (JasperException ex) { + } + HashMap map = psVisitor.getMap(); + // set up our SMAP generator SmapGenerator g = new SmapGenerator(); - + /** Disable reading of input SMAP because: 1. There is a bug here: getRealPath() is null if .jsp is in a jar Bugzilla 14660. @@ -126,8 +138,10 @@ SmapStratum s = new SmapStratum("JSP"); g.setOutputFileName(unqualify(ctxt.getServletJavaFileName())); + // Map out Node.Nodes - evaluateNodes(pageNodes, s, ctxt.getOptions().getMappedFile()); + evaluateNodes(pageNodes, s, map, ctxt.getOptions().getMappedFile()); + s.optimizeLineSection(); g.addStratum(s, true); if (ctxt.getOptions().isSmapDumped()) { @@ -140,17 +154,55 @@ so.print(g.getString()); so.close(); } - return g.getString(); + + String classFileName = ctxt.getClassFileName(); + int innerClassCount = map.size(); + String [] smapInfo = new String[2 + innerClassCount*2]; + smapInfo[0] = classFileName; + smapInfo[1] = g.getString(); + + int count = 2; + Iterator iter = map.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = (Map.Entry) iter.next(); + String innerClass = (String) entry.getKey(); + s = (SmapStratum) entry.getValue(); + s.optimizeLineSection(); + g = new SmapGenerator(); + g.setOutputFileName(unqualify(ctxt.getServletJavaFileName())); + g.addStratum(s, true); + + String innerClassFileName = + classFileName.substring(0, classFileName.indexOf(".class")) + + '$' + innerClass + ".class"; + if (ctxt.getOptions().isSmapDumped()) { + File outSmap = new File(innerClassFileName + ".smap"); + PrintWriter so = + new PrintWriter( + new OutputStreamWriter( + new FileOutputStream(outSmap), + SMAP_ENCODING)); + so.print(g.getString()); + so.close(); + } + smapInfo[count] = innerClassFileName; + smapInfo[count+1] = g.getString(); + count += 2; + } + + return smapInfo; } - public static void installSmap(String classFileName, String smap) + public static void installSmap(String[] smap) throws IOException { if (smap == null) { return; } - File outServlet = new File(classFileName); - SDEInstaller.install(outServlet, smap.getBytes()); + for (int i = 0; i < smap.length; i += 2) { + File outServlet = new File(smap[i]); + SDEInstaller.install(outServlet, smap[i+1].getBytes()); + } } //********************************************************************* @@ -497,22 +549,34 @@ public static void evaluateNodes( Node.Nodes nodes, SmapStratum s, + HashMap innerClassMap, boolean breakAtLF) { try { - nodes.visit(new SmapGenVisitor(s, breakAtLF)); + nodes.visit(new SmapGenVisitor(s, breakAtLF, innerClassMap)); } catch (JasperException ex) { } - s.optimizeLineSection(); } static class SmapGenVisitor extends Node.Visitor { private SmapStratum smap; private boolean breakAtLF; + private HashMap innerClassMap; - SmapGenVisitor(SmapStratum s, boolean breakAtLF) { + SmapGenVisitor(SmapStratum s, boolean breakAtLF, HashMap map) { this.smap = s; this.breakAtLF = breakAtLF; + this.innerClassMap = map; + } + + public void visitBody(Node n) throws JasperException { + SmapStratum smapSave = smap; + String innerClass = n.getInnerClassName(); + if (innerClass != null) { + this.smap = (SmapStratum) innerClassMap.get(innerClass); + } + super.visitBody(n); + smap = smapSave; } public void visit(Node.Declaration n) throws JasperException { @@ -697,6 +761,22 @@ } doSmap(n, lineCount, 1, skippedLines); + } + } + + private static class PreScanVisitor extends Node.Visitor { + + HashMap map = new HashMap(); + + public void doVisit(Node n) { + String inner = n.getInnerClassName(); + if (inner != null && !map.containsKey(inner)) { + map.put(inner, new SmapStratum("JSP")); + } + } + + HashMap getMap() { + return map; } } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]