Package org.apache.jasper.compiler

Source Code of org.apache.jasper.compiler.Compiler$JasperAntLogger

/*
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation.  All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution, if
*    any, must include the following acknowlegement: 
*       "This product includes software developed by the
*        Apache Software Foundation (http://www.apache.org/)."
*    Alternately, this acknowlegement may appear in the software itself,
*    if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
*    Foundation" must not be used to endorse or promote products derived
*    from this software without prior written permission. For written
*    permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
*    nor may "Apache" appear in their names without prior written
*    permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation.  For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
*/
package org.apache.jasper.compiler;

import java.util.*;
import java.io.*;
import java.net.URL;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.jsp.tagext.TagInfo;

import org.xml.sax.Attributes;

import org.apache.tools.ant.BuildEvent;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.BuildListener;
import org.apache.tools.ant.BuildLogger;
import org.apache.tools.ant.DefaultLogger;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.types.Path;
import org.apache.tools.ant.types.PatternSet;

import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.Constants;
import org.apache.jasper.JasperException;
import org.apache.jasper.Options;
import org.apache.jasper.logging.Logger;
import org.apache.jasper.util.SystemLogHandler;
import org.apache.jasper.runtime.HttpJspBase;
import org.apache.jasper.servlet.JspServletWrapper;

/**
* Main JSP compiler class. This class uses Ant for compiling.
*
* @author Anil K. Vijendran
* @author Mandar Raje
* @author Pierre Delisle
* @author Kin-man Chung
* @author Remy Maucherat
* @author Mark Roth
*/
public class Compiler {
    private static org.apache.commons.logging.Log log=
        org.apache.commons.logging.LogFactory.getLog( Compiler.class );

    // ----------------------------------------------------------------- Static


    static {

        System.setErr(new SystemLogHandler(System.err));

    }

    // Some javac are not thread safe; use a lock to serialize compilation,
    static Object javacLock = new Object();


    // ----------------------------------------------------- Instance Variables


    protected JspCompilationContext ctxt;

    private ErrorDispatcher errDispatcher;
    private PageInfo pageInfo;
    private JspServletWrapper jsw;
    private TagFileProcessor tfp;

    protected Project project=null;

    protected Options options;

    protected Node.Nodes pageNodes;
    // ------------------------------------------------------------ Constructor


    public Compiler(JspCompilationContext ctxt) {
        this(ctxt, null);
    }


    public Compiler(JspCompilationContext ctxt, JspServletWrapper jsw) {
        this.jsw = jsw;
        this.ctxt = ctxt;
  this.errDispatcher = new ErrorDispatcher();
        this.options = ctxt.getOptions();
    }

    // Lazy eval - if we don't need to compile we probably don't need the project
    private Project getProject() {
        if( project!=null ) return project;
        // Initializing project
        project = new Project();
        // XXX We should use a specialized logger to redirect to jasperlog
        //        DefaultLogger bl=new JasperAntLogger();
        DefaultLogger bl=new DefaultLogger();
        bl.setOutputPrintStream(System.err);
        bl.setErrorPrintStream(System.err);

        if( Constants.jasperLog.getVerbosityLevel() >= Logger.DEBUG ) {
            bl.setMessageOutputLevel( Project.MSG_VERBOSE );
        } else {
            bl.setMessageOutputLevel( Project.MSG_INFO );
        }
        if( log.isTraceEnabled() ) {
            bl.setMessageOutputLevel( Project.MSG_VERBOSE );
        }
        project.addBuildListener( bl );
       
        if( options.getCompiler() != null ) {
            if( log.isDebugEnabled() )
                log.debug("Compiler " + options.getCompiler() );
            project.setProperty("build.compiler", options.getCompiler() );
        }
        project.init();
//         Vector v=project.getBuildListeners();
//         if( v.size() > 0 ) {
//             BuildListener bl=(BuildListener)v.elementAt(0);
//             System.out.println("XXX " + bl );
//             ((DefaultLogger)bl).setMessageOutputLevel(Project.MSG_VERBOSE);
//         }
        return project;
    }

    static class JasperAntLogger extends DefaultLogger {
        private static org.apache.commons.logging.Log log=
            org.apache.commons.logging.LogFactory.getLog( Compiler.class );
        protected void printMessage(final String message,
                                    final PrintStream stream,
                                    final int priority) {
            log.info( message );
        }
    }

    // --------------------------------------------------------- Public Methods


    /**
     * Compile the jsp file from the current engine context
     */
    public void generateJava()
        throws Exception
    {
        long t1=System.currentTimeMillis();
  // Setup page info area
  pageInfo = new PageInfo(new BeanRepository(ctxt.getClassLoader()));
  JspConfig jspConfig = options.getJspConfig();
  JspConfig.JspProperty jspProperty =
      jspConfig.findJspProperty(ctxt.getJspFile());
  if (jspProperty != null) {
      // If the current uri is matched by a pattern specified in
      // a jsp-property-group in web.xml, initialize pageInfo with
      // those properties.
      if (jspProperty.isXml() != null) {
    pageInfo.setIsXmlSpecified(true);
      }
      if (jspProperty.isELIgnored() != null) {
    pageInfo.setELIgnoredSpecified(true);
      }
      pageInfo.setIsXml(JspUtil.booleanValue(jspProperty.isXml()));
      pageInfo.setPageEncoding(jspProperty.getPageEncoding());
      pageInfo.setELIgnored(JspUtil.booleanValue(jspProperty.isELIgnored()));
      pageInfo.setScriptingInvalid(JspUtil.booleanValue(jspProperty.isScriptingInvalid()));
      pageInfo.setIncludePrelude(jspProperty.getIncludePrelude());
      pageInfo.setIncludeCoda(jspProperty.getIncludeCoda());
  }

        String javaFileName = ctxt.getServletJavaFileName();

        // Setup the ServletWriter
  // We try UTF8 by default. If it fails, we use the java encoding
  // specified for JspServlet init parameter "javaEncoding".

  String javaEncoding = "UTF8";
  OutputStreamWriter osw = null;
  try {
      osw = new OutputStreamWriter(new FileOutputStream(javaFileName),
           javaEncoding);
  } catch (UnsupportedEncodingException ex) {
      // Try to get the java encoding from the "javaEncoding"
      // init parameter for JspServlet.
      javaEncoding = ctxt.getOptions().getJavaEncoding();
      if (javaEncoding != null) {
    try {
        osw = new OutputStreamWriter
                        (new FileOutputStream(javaFileName),javaEncoding);
    } catch (UnsupportedEncodingException ex2) {
        // no luck :-(
        errDispatcher.jspError("jsp.error.invalid.javaEncoding",
             "UTF8", javaEncoding);
    }
      } else {
    errDispatcher.jspError("jsp.error.needAlternateJavaEncoding",
               "UTF8");
      }
  }

  ServletWriter writer = new ServletWriter(new PrintWriter(osw));
        ctxt.setWriter(writer);

        // Reset the temporary variable counter for the generator.
        JspUtil.resetTemporaryVariableName();

  // Parse the file
  ParserController parserCtl = new ParserController(ctxt, this);
  pageNodes = parserCtl.parse(ctxt.getJspFile());

  if (ctxt.isPrototypeMode()) {
      // generate prototype .java file for the tag file
      Generator.generate(writer, this, pageNodes);
            writer.close();
      return;
  }

  // Validate and process attributes
  Validator.validate(this, pageNodes);

        long t2=System.currentTimeMillis();
  // Dump out the page (for debugging)
  // Dumper.dump(pageNodes);

  // Collect page info
  Collector.collect(this, pageNodes);

  // Compile (if necessary) and load the tag files referenced in
  // this compilation unit.
  tfp = new TagFileProcessor();
  tfp.loadTagFiles(this, pageNodes);

        long t3=System.currentTimeMillis();
       
  // Determine which custom tag needs to declare which scripting vars
  ScriptingVariabler.set(pageNodes, errDispatcher);

  // generate servlet .java file
  Generator.generate(writer, this, pageNodes);
        writer.close();

        long t4=System.currentTimeMillis();
        if( t4-t1 > 500 ) {
            log.debug("Generated "+ javaFileName + " total=" +
                      (t4-t1) + " generate=" + ( t4-t3 ) + " validate=" + ( t2-t1 ));
        }
       
        //JSR45 Support - note this needs to be checked by a JSR45 guru
  SmapUtil.generateSmap(ctxt, pageNodes, true);

  // If any proto type .java and .class files was generated,
  // the prototype .java may have been replaced by the current
  // compilation (if the tag file is self referencing), but the
  // .class file need to be removed, to make sure that javac would
  // generate .class again from the new .java file just generated.

  tfp.removeProtoTypeFiles(ctxt.getClassFileName());
    }

    /**
     * Compile the jsp file from the current engine context
     */
    public void generateClass()
        throws FileNotFoundException, JasperException, Exception {

        long t1=System.currentTimeMillis();
  String javaEncoding = "UTF8";
        String javaFileName = ctxt.getServletJavaFileName();
        String classpath = ctxt.getClassPath();

        String sep = System.getProperty("path.separator");

        String errorReport = null;
        boolean success = true;

        // Start capturing the System.err output for this thread
        SystemLogHandler.setThread();

        // Initializing javac task
        getProject();
        Javac javac = (Javac) project.createTask("javac");

        // Initializing classpath
        Path path = new Path(project);
        path.setPath(System.getProperty("java.class.path"));
        StringTokenizer tokenizer = new StringTokenizer(classpath, sep);
        while (tokenizer.hasMoreElements()) {
            String pathElement = tokenizer.nextToken();
            File repository = new File(pathElement);
            path.setLocation(repository);
        }

        if( log.isDebugEnabled() )
            log.debug( "Using classpath: " + System.getProperty("java.class.path") + sep
                       + classpath);
       
        // Initializing sourcepath
        Path srcPath = new Path(project);
        srcPath.setLocation(options.getScratchDir());

        // Configure the compiler object
        javac.setEncoding(javaEncoding);
        javac.setClasspath(path);
        javac.setDebug(ctxt.getOptions().getClassDebugInfo());
        javac.setSrcdir(srcPath);
        javac.setOptimize(! ctxt.getOptions().getClassDebugInfo() );

        // Set the Java compiler to use
        if (options.getCompiler() != null) {
            javac.setCompiler(options.getCompiler());
        }

        // Build includes path
        PatternSet.NameEntry includes = javac.createInclude();
        includes.setName(ctxt.getJspPath());

        try {
            synchronized(javacLock) {
                javac.execute();
            }
        } catch (BuildException e) {
            log.error( "Javac execption ", e);
            success = false;
        }

        // Stop capturing the System.err output for this thread
        errorReport = SystemLogHandler.unsetThread();
       
        if (!ctxt.keepGenerated()) {
            File javaFile = new File(javaFileName);
            javaFile.delete();
        }

        if (!success) {
            log.error( "Error compiling file: " + javaFileName + " " + errorReport);
            if(errorReport!=null )
                errDispatcher.javacError(errorReport, javaFileName, pageNodes);
        }

        long t2=System.currentTimeMillis();
        if( t2-t1 > 500 ) {
            log.debug( "Compiled " + javaFileName + " " + (t2-t1));
        }

  if (ctxt.isPrototypeMode()) {
      return;
  }

        //JSR45 Support - note this needs to be checked by a JSR45 guru
  SmapUtil.installSmap(ctxt);
    }

    /**
     * Compile the jsp file from the current engine context
     */
    public void compile()
        throws FileNotFoundException, JasperException, Exception
    {
        generateJava();
        generateClass();
  if (tfp != null) {
      tfp.removeProtoTypeFiles(null);
  }
    }

    /**
     * This is a protected method intended to be overridden by
     * subclasses of Compiler. This is used by the compile method
     * to do all the compilation.
     */
    public boolean isOutDated() {
        return isOutDated( true );
    }

    /**
     * This is a protected method intended to be overridden by
     * subclasses of Compiler. This is used by the compile method
     * to do all the compilation.
     * @param checkClass Verify the class file if true, only the .java file if false.
     */
    public boolean isOutDated(boolean checkClass) {

        String jsp = ctxt.getJspFile();

        long jspRealLastModified = 0;
        try {
            URL jspUrl = ctxt.getResource(jsp);
            if (jspUrl == null) {
                ctxt.incrementRemoved();
                return false;
            }
            jspRealLastModified = jspUrl.openConnection().getLastModified();
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }

        long targetLastModified;
        File targetFile;
       
        if( checkClass ) {
            targetFile = new File(ctxt.getClassFileName());
        } else {
            targetFile = new File(ctxt.getServletJavaFileName());
        }
       
        if (!targetFile.exists()) {
            return true;
        }

        targetLastModified = targetFile.lastModified();
        if (targetLastModified < jspRealLastModified) {
            if( log.isDebugEnabled() )
                log.debug("Compiler: outdated: " + targetFile + " " + targetLastModified );
            return true;
        }

        // determine if source dependent files (e.g. includes using include
  // directives) have been changed.
        if( jsw==null ) {
            return false;
        }

        List depends = jsw.getDependants();
        if (depends == null) {
            return false;
        }

        Iterator it = depends.iterator();
        while (it.hasNext()) {
            String include = (String)it.next();
            try {
                URL includeUrl = ctxt.getResource(include);
                if (includeUrl == null) {
                    //System.out.println("Compiler: outdated, no includeUri " + include );
                    return true;
                }
                if (includeUrl.openConnection().getLastModified() >
                    targetLastModified) {
                    //System.out.println("Compiler: outdated, include old " + include );
                    return true;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return true;
            }
        }
        return false;

    }

   
    /**
     * Gets the error dispatcher.
     */
    public ErrorDispatcher getErrorDispatcher() {
  return errDispatcher;
    }


    /**
     * Gets the info about the page under compilation
     */
    public PageInfo getPageInfo() {
  return pageInfo;
    }


    public JspCompilationContext getCompilationContext() {
  return ctxt;
    }


    /**
     * Remove generated files
     */
    public void removeGeneratedFiles() {
        try {
            String classFileName = ctxt.getClassFileName();
            if (classFileName != null) {
                File classFile = new File(classFileName);
                if( log.isDebugEnabled() )
                    log.debug( "Deleting " + classFile );
                classFile.delete();
            }
        } catch (Exception e) {
            // Remove as much as possible, ignore possible exceptions
        }
        try {
            String javaFileName = ctxt.getServletJavaFileName();
            if (javaFileName != null) {
                File javaFile = new File(javaFileName);
                if( log.isDebugEnabled() )
                    log.debug( "Deleting " + javaFile );
                javaFile.delete();
            }
        } catch (Exception e) {
            // Remove as much as possible, ignore possible exceptions
        }
    }

    public void removeGeneratedClassFiles() {
        try {
            String classFileName = ctxt.getClassFileName();
            if (classFileName != null) {
                File classFile = new File(classFileName);
                if( log.isDebugEnabled() )
                    log.debug( "Deleting " + classFile );
                classFile.delete();
            }
        } catch (Exception e) {
            // Remove as much as possible, ignore possible exceptions
        }
    }
}
TOP

Related Classes of org.apache.jasper.compiler.Compiler$JasperAntLogger

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.