Methods Summary |
---|
public void | compile()Compile the jsp file from the current engine context
compile(true);
|
public void | compile(boolean compileClass)Compile the jsp file from the current engine context. As an side- effect,
tag files that are referenced by this page are also compiled.
compile(compileClass, false);
|
public void | compile(boolean compileClass, boolean jspcMode)Compile the jsp file from the current engine context. As an side- effect,
tag files that are referenced by this page are also compiled.
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);
}
}
|
protected abstract void | generateClass(java.lang.String[] smap)Compile the servlet from .java file to .class file
|
protected java.lang.String[] | generateJava()Compile the jsp file into equivalent servlet in .java file
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 {
// Setup the ServletWriter
String javaEncoding = ctxt.getOptions().getJavaEncoding();
OutputStreamWriter osw = null;
try {
osw = new OutputStreamWriter(
new FileOutputStream(javaFileName), javaEncoding);
} catch (UnsupportedEncodingException ex) {
errDispatcher.jspError("jsp.error.needAlternateJavaEncoding",
javaEncoding);
}
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();
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
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;
|
public org.apache.jasper.JspCompilationContext | getCompilationContext()
return ctxt;
|
public ErrorDispatcher | getErrorDispatcher()Gets the error dispatcher.
return errDispatcher;
|
public PageInfo | getPageInfo()Gets the info about the page under compilation
return pageInfo;
|
public Node.Nodes | getPageNodes()
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.
return this.pageNodes;
|
public void | init(org.apache.jasper.JspCompilationContext ctxt, org.apache.jasper.servlet.JspServletWrapper jsw)
// ------------------------------------------------------------ Constructor
this.jsw = jsw;
this.ctxt = ctxt;
this.options = ctxt.getOptions();
|
public boolean | isOutDated()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.
return isOutDated(true);
|
public boolean | isOutDated(boolean checkClass)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.
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;
|
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()Remove generated files
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
}
|