Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   * 
   *      http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.apache.jasper.compiler;
 
 import static org.jboss.web.JasperMessages.MESSAGES;
 
 import java.io.File;
 import java.net.URL;
 import java.util.List;
 
Main JSP compiler class. This class uses Ant for compiling.

Author(s):
Anil K. Vijendran
Mandar Raje
Pierre Delisle
Kin-man Chung
Remy Maucherat
Mark Roth
 
 public abstract class Compiler {
     
     // ----------------------------------------------------- Instance Variables
 
     protected JspCompilationContext ctxt;
 
     protected ErrorDispatcher errDispatcher;
 
     protected PageInfo pageInfo;
 
     protected JspServletWrapper jsw;
 
     protected TagFileProcessor tfp;
 
     protected Options options;
 
     protected Node.Nodes pageNodes;
 
     // ------------------------------------------------------------ Constructor
 
     public void init(JspCompilationContext ctxtJspServletWrapper jsw) {
         this. = jsw;
         this. = ctxt;
         this. = ctxt.getOptions();
     }
 
     // --------------------------------------------------------- Public Methods
 
    

Retrieves the parsed nodes of the JSP page, if they are available. May return null. Used in development mode for generating detailed error messages. http://issues.apache.org/bugzilla/show_bug.cgi?id=37062.

 
     public Node.Nodes getPageNodes() {
         return this.;
     }

    
Compile the jsp file into equivalent servlet in .java file

Returns:
a smap for the current JSP page, if one is generated, null otherwise
 
     protected String[] generateJava() throws Exception {
 
         String[] smapStr = null;
 
         long t1t2t3t4;
        t1 = t2 = t3 = t4 = 0;
            t1 = System.currentTimeMillis();
        }
        // Setup page info area
         = new PageInfo(new BeanRepository(.getClassLoader(),
                ), .getJspFile(), .isTagFile());
        JspConfig jspConfig = .getJspConfig();
        JspConfig.JspProperty jspProperty = jspConfig.findJspProperty(
                .getJspFile());
        /*
         * 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.isELIgnored() != null) {
            .setELIgnored(JspUtil.booleanValue(jspProperty
                    .isELIgnored()));
        }
        if (jspProperty.isScriptingInvalid() != null) {
            .setScriptingInvalid(JspUtil.booleanValue(jspProperty
                    .isScriptingInvalid()));
        }
        if (jspProperty.getIncludePrelude() != null) {
            .setIncludePrelude(jspProperty.getIncludePrelude());
        }
        if (jspProperty.getIncludeCoda() != null) {
            .setIncludeCoda(jspProperty.getIncludeCoda());
        }
        if (jspProperty.isDeferedSyntaxAllowedAsLiteral() != null) {
            .setDeferredSyntaxAllowedAsLiteral(JspUtil.booleanValue(jspProperty
                    .isDeferedSyntaxAllowedAsLiteral()));
        }
        if (jspProperty.isTrimDirectiveWhitespaces() != null) {
            .setTrimDirectiveWhitespaces(JspUtil.booleanValue(jspProperty
                    .isTrimDirectiveWhitespaces()));
        }
        // Default ContentType processing is deferred until after the page has been parsed
        if (jspProperty.getBuffer() != null && .getBufferValue() == null) {
            .setBufferValue(jspProperty.getBuffer(), );
        }
        if (jspProperty.isErrorOnUndeclaredNamespace() != null) {
            .setErrorOnUndeclaredNamespace(JspUtil.booleanValue(jspProperty
                    .isErrorOnUndeclaredNamespace()));
        }
        if (.isTagFile()) {
            try {
                double libraryVersion = Double.parseDouble(.getTagInfo()
                        .getTagLibrary().getRequiredVersion());
                if (libraryVersion < 2.0) {
                    .setIsELIgnored("true"nulltrue);
                }
                if (libraryVersion < 2.1) {
                    .setDeferredSyntaxAllowedAsLiteral("true"null,
                            true);
                }
            } catch (NumberFormatException ex) {
                .jspError(.malformedLibraryVersionNumber(), ex);
            }
        }
        .checkOutputDir();
        String javaFileName = .getServletJavaFileName();
        ServletWriter writer = null;
        try {
            /*
             * The setting of isELIgnored changes the behaviour of the parser
             * in subtle ways. To add to the 'fun', isELIgnored can be set in
             * any file that forms part of the translation unit so setting it
             * in a file included towards the end of the translation unit can
             * change how the parser should have behaved when parsing content
             * up to the point where isELIgnored was set. Arghh!
             * Previous attempts to hack around this have only provided partial
             * solutions. We now use two passes to parse the translation unit.
             * The first just parses the directives and the second parses the
             * whole translation unit once we know how isELIgnored has been set.
             * TODO There are some possible optimisations of this process.  
             */ 
            // Parse the file
            ParserController parserCtl = new ParserController(this);
            
            // Pass 1 - the directives
            Node.Nodes directives =
                parserCtl.parseDirectives(.getJspFile());
            Validator.validateDirectives(thisdirectives);
            
            // Pass 2 - the whole translation unit
             = parserCtl.parse(.getJspFile());
            if (jspProperty.getDefaultContentType() != null && .getContentType() == null) {
                .setContentType(jspProperty.getDefaultContentType());
            }
            if (.isPrototypeMode()) {
                // generate prototype .java file for the tag file
                writer = setupContextWriter(javaFileName);
                Generator.generate(writerthis);
                writer.close();
                writer = null;
                return null;
            }
            // Validate and process attributes - don't re-validate the
            // directives we validated in pass 1
            Validator.validateExDirectives(this);
            if (..isDebugEnabled()) {
                t2 = System.currentTimeMillis();
            }
            // Collect page info
            Collector.collect(this);
            // Compile (if necessary) and load the tag files referenced in
            // this compilation unit.
             = new TagFileProcessor();
            .loadTagFiles(this);
            if (..isDebugEnabled()) {
                t3 = System.currentTimeMillis();
            }
            // Determine which custom tag needs to declare which scripting vars
            ScriptingVariabler.set();
            // Optimizations by Tag Plugins
            TagPluginManager tagPluginManager = .getTagPluginManager();
            tagPluginManager.apply();
            // Optimization: concatenate contiguous template texts.
            TextOptimizer.concatenate(this);
            // Generate static function mapper codes.
            ELFunctionMapper.map();
            // generate servlet .java file
            writer = setupContextWriter(javaFileName);
            Generator.generate(writerthis);
            writer.close();
            writer = null;
            // The writer is only used during the compile, dereference
            // it in the JspCompilationContext when done to allow it
            // to be GC'd and save memory.
            .setWriter(null);
            if (..isDebugEnabled()) {
                t4 = System.currentTimeMillis();
                ..debug("Generated " + javaFileName + " total=" + (t4 - t1)
                        + " generate=" + (t4 - t3) + " validate=" + (t2 - t1));
            }
        } catch (Exception e) {
            if (writer != null) {
                try {
                    writer.close();
                    writer = null;
                } catch (Exception e1) {
                    // do nothing
                }
            }
            // Remove the generated .java file
            new File(javaFileName).delete();
            throw e;
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (Exception e2) {
                    // do nothing
                }
            }
        }
        // JSR45 Support
        if (!.isSmapSuppressed()) {
            smapStr = SmapUtil.generateSmap();
        }
        // 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.
        return smapStr;
    }
	private ServletWriter setupContextWriter(String javaFileName)
		// Setup the ServletWriter
		String javaEncoding = .getOptions().getJavaEncoding();
		OutputStreamWriter osw = null;
		try {
		    osw = new OutputStreamWriter(
		            new FileOutputStream(javaFileName), javaEncoding);
		}
		writer = new ServletWriter(new PrintWriter(osw));
		.setWriter(writer);
		return writer;
	}

    
Compile the servlet from .java file to .class file
    protected abstract void generateClass(String[] smap)
            throws FileNotFoundExceptionJasperExceptionException;

    
Compile the jsp file from the current engine context
    public void compile() throws FileNotFoundExceptionJasperException,
            Exception {
        compile(true);
    }

    
Compile the jsp file from the current engine context. As an side- effect, tag files that are referenced by this page are also compiled.

Parameters:
compileClass If true, generate both .java and .class file If false, generate only .java file
    public void compile(boolean compileClassthrows FileNotFoundException,
            JasperExceptionException {
        compile(compileClassfalse);
    }

    
Compile the jsp file from the current engine context. As an side- effect, tag files that are referenced by this page are also compiled.

Parameters:
compileClass If true, generate both .java and .class file If false, generate only .java file
jspcMode true if invoked from JspC, false otherwise
    public void compile(boolean compileClassboolean jspcMode)
            throws FileNotFoundExceptionJasperExceptionException {
        if ( == null) {
            this. = new ErrorDispatcher(jspcMode);
        }
        try {
            String[] smap = generateJava();
            if (compileClass) {
                generateClass(smap);
                // Set JspServletWrapper.servletClassLastModifiedTime after successful compile
                String targetFileName = .getClassFileName();
                if (targetFileName != null) {
                    File targetFile = new File(targetFileName);
                    if (targetFile.exists() &&  != null) {
                        .setServletClassLastModifiedTime(targetFile.lastModified());
                    }
                }
            }
        } finally {
            if ( != null) {
                .removeProtoTypeFiles(null);
            }
            // Make sure these object which are only used during the
            // generation and compilation of the JSP page get
            // dereferenced so that they can be GC'd and reduce the
            // memory footprint.
             = null;
             = null;
             = null;
            // Only get rid of the pageNodes if in production.
            // In development mode, they are used for detailed
            // error messages.
            // http://issues.apache.org/bugzilla/show_bug.cgi?id=37062
            if (!this..getDevelopment()) {
                 = null;
            }
            if (.getWriter() != null) {
                .getWriter().close();
                .setWriter(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);
    }

    
Determine if a compilation is necessary by checking the time stamp of the JSP page with that of the corresponding .class or .java file. If the page has dependencies, the check is also extended to its dependeants, and so on. This method can by overidden by a subclasses of Compiler.

Parameters:
checkClass If true, check against .class file, if false, check against .java file.
    public boolean isOutDated(boolean checkClass) {
        String jsp = .getJspFile();
        if ( != null
                && (.getOptions().getModificationTestInterval() > 0)) {
            if (.getLastModificationTest()
                    + (.getOptions().getModificationTestInterval() * 1000) > System
                    .currentTimeMillis()) {
                return false;
            } else {
                .setLastModificationTest(System.currentTimeMillis());
            }
        }
        long jspRealLastModified = 0;
        try {
            URL jspUrl = .getResource(jsp);
            if (jspUrl == null) {
                .incrementRemoved();
                return false;
            }
            URLConnection uc = jspUrl.openConnection();
            if (uc instanceof JarURLConnection) {
                jspRealLastModified =
                    ((JarURLConnectionuc).getJarEntry().getTime();
            } else {
                jspRealLastModified = uc.getLastModified();
            }
            uc.getInputStream().close();
        } catch (Exception e) {
            return true;
        }
        long targetLastModified = 0;
        File targetFile;
        if (checkClass) {
            targetFile = new File(.getClassFileName());
        } else {
            targetFile = new File(.getServletJavaFileName());
        }
        if (!targetFile.exists()) {
            return true;
        }
        targetLastModified = targetFile.lastModified();
        if (checkClass &&  != null) {
            .setServletClassLastModifiedTime(targetLastModified);
        }
        if (targetLastModified < jspRealLastModified) {
            if (..isDebugEnabled()) {
                ..debug("Compiler: outdated: " + targetFile + " "
                        + targetLastModified);
            }
            return true;
        }
        // determine if source dependent files (e.g. includes using include
        // directives) have been changed.
        if ( == null) {
            return false;
        }
        List depends = .getDependants();
        if (depends == null) {
            return false;
        }
        Iterator it = depends.iterator();
        while (it.hasNext()) {
            String include = (Stringit.next();
            try {
                URL includeUrl = .getResource(include);
                if (includeUrl == null) {
                    return true;
                }
                URLConnection iuc = includeUrl.openConnection();
                long includeLastModified = 0;
                if (iuc instanceof JarURLConnection) {
                    includeLastModified =
                        ((JarURLConnectioniuc).getJarEntry().getTime();
                } else {
                    includeLastModified = iuc.getLastModified();
                }
                iuc.getInputStream().close();
                if (includeLastModified > targetLastModified) {
                    return true;
                }
            } catch (Exception e) {
                return true;
            }
        }
        return false;
    }

    
Gets the error dispatcher.
        return ;
    }

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

    
Remove generated files
    public void removeGeneratedFiles() {
        try {
            String classFileName = .getClassFileName();
            if (classFileName != null) {
                File classFile = new File(classFileName);
                if (..isDebugEnabled())
                    ..debug("Deleting " + classFile);
                classFile.delete();
            }
        } catch (Exception e) {
            // Remove as much as possible, ignore possible exceptions
        }
        try {
            String javaFileName = .getServletJavaFileName();
            if (javaFileName != null) {
                File javaFile = new File(javaFileName);
                if (..isDebugEnabled())
                    ..debug("Deleting " + javaFile);
                javaFile.delete();
            }
        } catch (Exception e) {
            // Remove as much as possible, ignore possible exceptions
        }
    }
    public void removeGeneratedClassFiles() {
        try {
            String classFileName = .getClassFileName();
            if (classFileName != null) {
                File classFile = new File(classFileName);
                if (..isDebugEnabled())
                    ..debug("Deleting " + classFile);
                classFile.delete();
            }
        } catch (Exception e) {
            // Remove as much as possible, ignore possible exceptions
        }
    }
New to GrepCode? Check out our FAQ X