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() 
+")";
  +    }
  +    
  +    
   }
  
  
  

Reply via email to