You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by co...@apache.org on 2001/06/06 08:12:47 UTC
cvs commit: jakarta-tomcat-jasper/jasper34/generator/org/apache/jasper34/generator ServletWriter.java
costin 01/06/05 23:12:47
Modified: jasper34/generator/org/apache/jasper34/generator
ServletWriter.java
Log:
Expanded ServletWriter ( with methods from JspParseEventListener ). Still
need to be simplified, by adding few more callbacks ( and allowing
generators to play with more methods )
Revision Changes Path
1.2 +390 -103 jakarta-tomcat-jasper/jasper34/generator/org/apache/jasper34/generator/ServletWriter.java
Index: ServletWriter.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-jasper/jasper34/generator/org/apache/jasper34/generator/ServletWriter.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ServletWriter.java 2001/05/27 23:19:31 1.1
+++ ServletWriter.java 2001/06/06 06:12:45 1.2
@@ -1,8 +1,4 @@
/*
- * $Header: /home/cvs/jakarta-tomcat-jasper/jasper34/generator/org/apache/jasper34/generator/ServletWriter.java,v 1.1 2001/05/27 23:19:31 costin Exp $
- * $Revision: 1.1 $
- * $Date: 2001/05/27 23:19:31 $
- *
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -59,132 +55,423 @@
*
*/
package org.apache.jasper34.generator;
+
+import java.io.*;
+import java.util.*;
-import java.io.PrintWriter;
-import java.io.BufferedReader;
-import java.io.StringReader;
-import java.io.IOException;
+import org.apache.jasper34.javagen.*;
+import org.apache.jasper34.core.*;
+import org.apache.jasper34.runtime.*;
+import org.apache.jasper34.parser.*;
+import org.apache.jasper34.jsptree.*;
/**
- * This is what is used to generate servlets.
+ * This is what is used to generate servlets.
+ * Derived from the generic java code generator.
*
* @author Anil K. Vijendran
+ * @author Costin Manolache
*/
-public class ServletWriter {
- public static int TAB_WIDTH = 4;
- public static String SPACES = " ";
+public class ServletWriter extends JavaSourceGenerator {
+
+ public ServletWriter(PrintWriter writer) {
+ super( writer );
+ }
+
+ public void generateServlet(JspCompilationContext ctxt,
+ JspPageInfo pageInfo )
+ throws JasperException
+ {
+ // Do we need that ??
+ ctxt.setContentType(pageInfo.servletContentType);
+
+ generateHeader(pageInfo);
+
+ generateClassDeclarations(pageInfo );
+
+ generateStaticInit(pageInfo );
- // Current indent level:
- int indent = 0;
+ generateConstructor(pageInfo );
+
+ generateJspxInit( pageInfo );
+
+ generateGetPageContext( pageInfo );
+
+ generateServiceMethod( pageInfo );
+
+ generateJspService(pageInfo);
+
+ this.generateClassFooter();
+
+ // Generate additional file for large chunks
+ generateChunksDat( pageInfo );
+ }
+
- // The sink writer:
- PrintWriter writer;
+ // -------------------- Code generators --------------------
+
+ private void generateHeader(JspPageInfo pageInfo)
+ throws JasperException
+ {
+ String servletPackageName = pageInfo.getServletPackageName();
+ String servletClassName = pageInfo.getServletClassName();
+ // First the package name:
+ this.setPackage( servletPackageName );
+
+ Enumeration e = pageInfo.imports.elements();
+ while (e.hasMoreElements())
+ this.addImport((String) e.nextElement());
+
+ this.generateHeader();
+
+ for(int i = 0; i < pageInfo.generators.size(); i++) {
+ GeneratorBase gen=(GeneratorBase)pageInfo.generators.elementAt(i);
+ //gen.startComment(this);
+ gen.generateFileDeclaration(this);
+ //gen.endComment(this);
+ }
+
+ this.setClassName( servletClassName );
+ this.setExtendClass( pageInfo.extendsClass.equals("") ?
+ pageInfo.jspServletBase : pageInfo.extendsClass);
+
+ if (pageInfo.singleThreaded)
+ pageInfo.interfaces.addElement("SingleThreadModel");
+
+ if (pageInfo.interfaces.size() != 0) {
+ for(int i = 0; i < pageInfo.interfaces.size() ; i++)
+ this.addInterface((String)pageInfo.interfaces.elementAt(i));
+ }
+
+ this.generateClassHeader();
+ }
- public ServletWriter(PrintWriter writer) {
- this.writer = writer;
+ private void generateClassDeclarations(JspPageInfo pageInfo)
+ throws JasperException
+ {
+ for(int i = 0; i < pageInfo.generators.size(); i++) {
+ GeneratorBase gen=(GeneratorBase)pageInfo.generators.elementAt(i);
+ //gen.startComment(this);
+ gen.generateClassDeclaration(this);
+ //gen.endComment(this);
+ }
+
+ this.println();
}
- public void close() throws IOException {
- writer.close();
+ private void generateJspService(JspPageInfo pageInfo)
+ throws JasperException
+ {
+ this.println("public void _jspService("+
+ "PageContext pageContext, " +
+ "HttpServletRequest request, "+
+ "HttpServletResponse response)");
+ this.println(" throws Throwable ");
+ this.println("{");
+
+ this.pushIndent();
+ if (pageInfo.contentTypeDir == true)
+ this.println("response.setContentType(" +
+ this.quoteString(pageInfo.servletContentType)
+ + ");");
+ else
+ this.println("response.setContentType(\"" +
+ pageInfo.servletContentType +
+ ";charset=8859_1\");");
+
+ if (pageInfo.isErrorPage())
+ this.println("Throwable exception = (Throwable) request.getAttribute(\"javax.servlet.jsp.jspException\");");
+ this.println("Object page = this;");
+ this.println("String _value = null;");
+ this.println("ServletContext application = pageContext.getServletContext();");
+ this.println("ServletConfig config = pageContext.getServletConfig();");
+ this.println("JspWriter out = pageContext.getOut();");
+
+ if (pageInfo.genSessionVariable)
+ this.println("HttpSession session = pageContext.getSession();");
+
+ this.println();
+
+ // We can use tc hooks
+ for(int i = 0; i < pageInfo.generators.size(); i++) {
+ GeneratorBase gen=(GeneratorBase)pageInfo.generators.elementAt(i);
+ generateStartComment(gen);
+ gen.generateServiceMethod(this);
+ generateEndComment(gen);
+ }
+ this.println();
+ this.popIndent();
+
+ // Close the class definition:
+ this.popIndent();
+ this.println("}");
+ }
+
+ private void generateStaticInit(JspPageInfo pageInfo )
+ throws JasperException
+ {
+ this.println("static {");
+ this.pushIndent();
+
+ for(int i = 0; i < pageInfo.generators.size(); i++) {
+ GeneratorBase gen=(GeneratorBase)pageInfo.generators.elementAt(i);
+ //gen.startComment(this);
+ gen.generateStaticInitializer(this);
+ //gen.endComment(this);
+ }
+
+ this.popIndent();
+ this.println("}");
}
+
+ private void generateConstructor(JspPageInfo pageInfo )
+ throws JasperException
+ {
+ this.println("public "+ pageInfo.getServletClassName()+"( ) {");
+ this.println("}");
+ this.println();
+ }
+
- public void pushIndent() {
- if ((indent += TAB_WIDTH) > SPACES.length())
- indent = SPACES.length();
+ private void generateJspxInit(JspPageInfo pageInfo )
+ throws JasperException
+ {
+ this.println("private boolean _jspx_inited = false;");
+ this.println();
+
+ this.println("public final synchronized void _jspx_init() throws " +
+ Constants.JSP_RUNTIME_PACKAGE + ".JasperException {");
+ this.pushIndent();
+ this.println("if (! _jspx_inited) {");
+ this.pushIndent();
+
+ for(int i = 0; i < pageInfo.generators.size(); i++) {
+ GeneratorBase gen=(GeneratorBase)pageInfo.generators.elementAt(i);
+ //gen.startComment(this);
+ gen.generateInitMethod(this);
+ //gen.endComment(this);
+ }
+
+ this.println("_jspx_inited = true;");
+ this.popIndent();
+ this.println("}");
+ this.popIndent();
+ this.println("}");
+ this.println();
}
+
+
- public void popIndent() {
- if ((indent -= TAB_WIDTH) <= 0 )
- indent = 0;
+ private void generateGetPageContext(JspPageInfo pageInfo )
+ throws JasperException
+ {
+ this.println("public final PageContext _getPageContext(HttpServletRequest request, " +
+ " HttpServletResponse response)");
+
+ this.println( "{" );
+ this.pushIndent();
+
+ // protected field _jspxFactory already defined in HttpJspBase
+ if( ! pageInfo.extendsClass.equals("") )
+ this.println("JspFactory _jspxFactory = JspFactory.getDefaultFactory();");
+
+
+ this.println("return _jspxFactory.getPageContext(this, request, response,\n"
+ + "\t\t\t"
+ + this.quoteString(pageInfo.error) + ", "
+ + pageInfo.genSessionVariable + ", "
+ + pageInfo.bufferSize + ", "
+ + pageInfo.autoFlush
+ + ");");
+ this.popIndent();
+ this.println("}");
+ this.println();
}
- /**
- * Print a standard comment for echo outputed chunk.
- * @param start The starting position of the JSP chunk being processed.
- * @param stop The ending position of the JSP chunk being processed.
- */
- public void printComment(Mark start, Mark stop, char[] chars) {
- if (start != null && stop != null) {
- println("// from="+start);
- println("// to="+stop);
- }
+
+ /** Generate serviceMethod - as required by the spec
+ Used only if the page extends something else than HttpJspBase
+ If HttpJspBase is used, the code is not needed, as it
+ replicates the code in it.
+ */
+ private void generateServiceMethod(JspPageInfo pageInfo )
+ throws JasperException
+ {
+ // if extends HttpJspBase, this method is already defined in supper
+ if( pageInfo.extendsClass.equals("") )
+ return;
+
+ this.println();
+
+ this.println("public void "+pageInfo.serviceMethodName+"("+
+ "HttpServletRequest request, "+
+ "HttpServletResponse response)");
+ this.println(" throws java.io.IOException, ServletException {");
+ this.pushIndent();
+
+ this.println();
+ this.println("JspFactory _jspxFactory = JspFactory.getDefaultFactory();");
+ this.println("PageContext pageContext = null;");
+
+ this.println("try {");
+ this.pushIndent();
+ this.println("try {");
+ this.pushIndent();
+
+ this.println();
+ this.println("_jspx_init();");
+
+ this.println("pageContext = _getPageContext(request, response);");
+ this.println();
+ this.println("_jspService( pageContext, request, response );");
+ //writer.println("} catch (Throwable t) {");
+ this.popIndent();
+ this.println("} catch (Exception ex) {");
+ this.pushIndent();
+ // Used to have a clearBuffer here, but it's moved in handlePageEx
+ this.println("if (pageContext != null) pageContext.handlePageException(ex);");
+ this.popIndent();
+ this.println("} catch (Error error) {");
+ this.pushIndent();
+ this.println("throw error;");
+ this.popIndent();
+ this.println("} catch (Throwable throwable) {");
+ this.pushIndent();
+ this.println("throw new ServletException(throwable);");
+ this.popIndent();
+ this.println("}");
+ this.popIndent();
+ this.println("} finally {");
+ this.pushIndent();
+ // Do stuff here for finally actions...
+ //writer.println("out.close();");
+
+ // Use flush buffer ( which just empty JspWriterImpl buffer )
+ // instead of commiting the response.
+ this.println("JspWriter out=pageContext.getOut();");
+ this.println("((" + Constants.JSP_RUNTIME_PACKAGE +
+ ".JspWriterImpl)out).flushBuffer();");
+ this.println("if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);");
+ this.popIndent();
+ this.println("}");
+ // Close the service method:
+ this.popIndent();
+ this.println("}");
+
+ this.println();
+ }
+
+
+
+// /**
+// * Print a standard comment for echo outputed chunk.
+// * @param start The starting position of the JSP chunk being processed.
+// * @param stop The ending position of the JSP chunk being processed.
+// */
+// public void printComment(Mark start, Mark stop, char[] chars) {
+// if (start != null && stop != null) {
+// println("// from="+start);
+// println("// to="+stop);
+// }
- if (chars != null)
- for(int i = 0; i < chars.length;) {
- indent();
- print("// ");
- while (chars[i] != '\n' && i < chars.length)
- writer.print(chars[i++]);
+// if (chars != null)
+// for(int i = 0; i < chars.length;) {
+// indent();
+// print("// ");
+// while (chars[i] != '\n' && i < chars.length)
+// writer.print(chars[i++]);
+// println();
+// }
+// }
+
+ private void generateChunksDat(JspPageInfo pageInfo )
+ throws JasperException
+ {
+
+ if (pageInfo.ctxt.getOptions().getLargeFile()) {
+ try {
+ FileOutputStream fos=new FileOutputStream(pageInfo.dataFile);
+ ObjectOutputStream o
+ = new ObjectOutputStream(fos);
+
+ /*
+ * Serialize an array of char[]'s instead of an
+ * array of String's because there is a limitation
+ * on the size of Strings that can be serialized.
+ */
+ char[][] tempCharArray = new char[pageInfo.vector.size()][];
+ pageInfo.vector.copyInto(tempCharArray);
+ o.writeObject(tempCharArray);
+ o.close();
+ this.close();
+ } catch (IOException ex) {
+ throw new JasperException(Constants.getString("jsp.error.data.file.write"), ex);
}
+ }
}
+ // -------------------- Generate comments --------------------
+ // The code generator also maintains line number info. Right now we generate
+ // some comments, later we'll add real mappings
+
/**
- * Quote the given string to make it appear in a chunk of java code.
- * @param s The string to quote.
- * @return The quoted string.
+ * Generates "start-of the JSP-embedded code block" comment
+ *
+ * @param start Start position of the block
+ * @param stop End position of the block
+ * @exception JasperException
*/
+ public void generateStartComment(GeneratorBase generator )
+ throws JasperException
+ {
+ // XXX Use emacs style or something common
+ Mark start=generator.start;
+ Mark stop=generator.stop;
+ String html = "";
+ if (generator instanceof CharDataGenerator) {
+ html = "// HTML ";
+ }
+ if (start != null && stop != null) {
+ if (start.getFile().equals( stop.getFile())) {
+ String fileName = this.quoteString(start.getFile ());
+ this.println(html + "// begin [file=" + fileName+";from=" +
+ toShortString(start) + ";to=" +
+ toShortString(stop) + "]");
+ } else {
+ this.println(html + "// begin [from="+toString(start)+
+ ";to="+toString(stop)+"]");
+ }
+ } else {
+ this.println(html + "// begin");
+ }
- public String quoteString(String s) {
- // Turn null string into quoted empty strings:
- if ( s == null )
- return "null";
- // Hard work:
- if ( s.indexOf('"') < 0 && s.indexOf('\\') < 0 && s.indexOf ('\n') < 0
- && s.indexOf ('\r') < 0)
- return "\""+s+"\"";
- StringBuffer sb = new StringBuffer();
- int len = s.length();
- sb.append('"');
- for (int i = 0 ; i < len ; i++) {
- char ch = s.charAt(i);
- if ( ch == '\\' && i+1 < len) {
- sb.append('\\');
- sb.append('\\');
- sb.append(s.charAt(++i));
- } else if ( ch == '"' ) {
- sb.append('\\');
- sb.append('"');
- } else if (ch == '\n') {
- sb.append ("\\n");
- }else if (ch == '\r') {
- sb.append ("\\r");
- }else {
- sb.append(ch);
- }
- }
- sb.append('"');
- return sb.toString();
- }
-
- public void println(String line) {
- writer.println(SPACES.substring(0, indent)+line);
- }
-
- public void println() {
- writer.println("");
- }
-
- public void indent() {
- writer.print(SPACES.substring(0, indent));
+ // this.pushIndent();
}
-
- public void print(String s) {
- writer.print(s);
- }
-
- public void printMultiLn(String multiline) {
- // Try to be smart (i.e. indent properly) at generating the code:
- BufferedReader reader =
- new BufferedReader(new StringReader(multiline));
- try {
- for (String line = null ; (line = reader.readLine()) != null ; )
- // println(SPACES.substring(0, indent)+line);
- println(line);
- } catch (IOException ex) {
- // Unlikely to happen, since we're acting on strings
- }
+ /**
+ * Generates "end-of the JSP-embedded code block" comment
+ *
+ * @param out The ServletWriter
+ * @param start Start position of the block
+ * @param stop End position of the block
+ * @exception JasperException
+ */
+ public void generateEndComment(GeneratorBase generator)
+ throws JasperException
+ {
+ // this.popIndent();
+ this.println("// end");
}
+ // The format may change
+ private String toShortString( Mark mark ) {
+ return "("+mark.getLineNumber() + ","+mark.getColumnNumber() +")";
+ }
+ //
+ private String toString( Mark mark ) {
+ return mark.getSystemId()+"("+mark.getLineNumber()+","+mark.getColumnNumber() +")";
+ }
+
+
}