| Method from org.apache.jasper.compiler.Compiler Detail: |
public void compile() throws Exception, JasperException, FileNotFoundException {
compile(true);
}
Compile the jsp file from the current engine context |
public void compile(boolean compileClass) throws Exception, JasperException, FileNotFoundException {
compile(compileClass, false);
}
Compile the jsp file from the current engine context. As an side- effect,
tag files that are referenced by this page are also compiled. |
public void compile(boolean compileClass,
boolean jspcMode) throws Exception, JasperException, FileNotFoundException {
if (errDispatcher == null) {
this.errDispatcher = new ErrorDispatcher(jspcMode);
}
try {
String[] smap = generateJava();
if (compileClass) {
generateClass(smap);
}
} finally {
if (tfp != null) {
tfp.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.
tfp = null;
errDispatcher = null;
pageInfo = 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.options.getDevelopment()) {
pageNodes = null;
}
if (ctxt.getWriter() != null) {
ctxt.getWriter().close();
ctxt.setWriter(null);
}
}
}
Compile the jsp file from the current engine context. As an side- effect,
tag files that are referenced by this page are also compiled. |
abstract protected void generateClass(String[] smap) throws Exception, JasperException, FileNotFoundException
Compile the servlet from .java file to .class file |
protected String[] generateJava() throws Exception {
String[] smapStr = null;
long t1, t2, t3, t4;
t1 = t2 = t3 = t4 = 0;
if (log.isDebugEnabled()) {
t1 = System.currentTimeMillis();
}
// Setup page info area
pageInfo = new PageInfo(new BeanRepository(ctxt.getClassLoader(),
errDispatcher), ctxt.getJspFile());
JspConfig jspConfig = options.getJspConfig();
JspConfig.JspProperty jspProperty = jspConfig.findJspProperty(ctxt
.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) {
pageInfo.setELIgnored(JspUtil.booleanValue(jspProperty
.isELIgnored()));
}
if (jspProperty.isScriptingInvalid() != null) {
pageInfo.setScriptingInvalid(JspUtil.booleanValue(jspProperty
.isScriptingInvalid()));
}
if (jspProperty.getIncludePrelude() != null) {
pageInfo.setIncludePrelude(jspProperty.getIncludePrelude());
}
if (jspProperty.getIncludeCoda() != null) {
pageInfo.setIncludeCoda(jspProperty.getIncludeCoda());
}
if (jspProperty.isDeferedSyntaxAllowedAsLiteral() != null) {
pageInfo.setDeferredSyntaxAllowedAsLiteral(JspUtil.booleanValue(jspProperty
.isDeferedSyntaxAllowedAsLiteral()));
}
if (jspProperty.isTrimDirectiveWhitespaces() != null) {
pageInfo.setTrimDirectiveWhitespaces(JspUtil.booleanValue(jspProperty
.isTrimDirectiveWhitespaces()));
}
ctxt.checkOutputDir();
String javaFileName = ctxt.getServletJavaFileName();
ServletWriter writer = null;
try {
// 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
writer = setupContextWriter(javaFileName);
Generator.generate(writer, this, pageNodes);
writer.close();
writer = null;
return null;
}
// Validate and process attributes
Validator.validate(this, pageNodes);
if (log.isDebugEnabled()) {
t2 = System.currentTimeMillis();
}
// 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);
if (log.isDebugEnabled()) {
t3 = System.currentTimeMillis();
}
// Determine which custom tag needs to declare which scripting vars
ScriptingVariabler.set(pageNodes, errDispatcher);
// Optimizations by Tag Plugins
TagPluginManager tagPluginManager = options.getTagPluginManager();
tagPluginManager.apply(pageNodes, errDispatcher, pageInfo);
// Optimization: concatenate contiguous template texts.
TextOptimizer.concatenate(this, pageNodes);
// Generate static function mapper codes.
ELFunctionMapper.map(this, pageNodes);
// generate servlet .java file
writer = setupContextWriter(javaFileName);
Generator.generate(writer, this, pageNodes);
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.
ctxt.setWriter(null);
if (log.isDebugEnabled()) {
t4 = System.currentTimeMillis();
log.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 (!options.isSmapSuppressed()) {
smapStr = SmapUtil.generateSmap(ctxt, pageNodes);
}
// 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());
return smapStr;
}
Compile the jsp file into equivalent servlet in .java file |
public JspCompilationContext getCompilationContext() {
return ctxt;
}
|
public ErrorDispatcher getErrorDispatcher() {
return errDispatcher;
}
Gets the error dispatcher. |
public PageInfo getPageInfo() {
return pageInfo;
}
Gets the info about the page under compilation |
public Node.Nodes getPageNodes() {
return this.pageNodes;
}
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 void init(JspCompilationContext ctxt,
JspServletWrapper jsw) {
// ------------------------------------------------------------ Constructor
this.jsw = jsw;
this.ctxt = ctxt;
this.options = ctxt.getOptions();
}
|
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. |
public boolean isOutDated(boolean checkClass) {
String jsp = ctxt.getJspFile();
if (jsw != null
&& (ctxt.getOptions().getModificationTestInterval() > 0)) {
if (jsw.getLastModificationTest()
+ (ctxt.getOptions().getModificationTestInterval() * 1000) > System
.currentTimeMillis()) {
return false;
} else {
jsw.setLastModificationTest(System.currentTimeMillis());
}
}
long jspRealLastModified = 0;
try {
URL jspUrl = ctxt.getResource(jsp);
if (jspUrl == null) {
ctxt.incrementRemoved();
return false;
}
URLConnection uc = jspUrl.openConnection();
jspRealLastModified = uc.getLastModified();
uc.getInputStream().close();
} catch (Exception e) {
return true;
}
long targetLastModified = 0;
File targetFile;
if (checkClass) {
targetFile = new File(ctxt.getClassFileName());
} else {
targetFile = new File(ctxt.getServletJavaFileName());
}
if (!targetFile.exists()) {
return true;
}
targetLastModified = targetFile.lastModified();
if (checkClass && jsw != null) {
jsw.setServletClassLastModifiedTime(targetLastModified);
}
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) {
return true;
}
URLConnection includeUconn = includeUrl.openConnection();
long includeLastModified = includeUconn.getLastModified();
includeUconn.getInputStream().close();
if (includeLastModified > targetLastModified) {
return true;
}
} catch (Exception e) {
return true;
}
}
return false;
}
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. |
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
}
}
|
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
}
}
|