com.caucho.jsp.JspCompilerInstance Maven / Gradle / Ivy
/*
* Copyright (c) 1998-2018 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Resin Open Source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
* of NON-INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
* Free Software Foundation, Inc.
* 59 Temple Place, Suite 330
* Boston, MA 02111-1307 USA
*
* @author Scott Ferguson
*/
package com.caucho.jsp;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.jsp.tagext.TagInfo;
import javax.servlet.jsp.tagext.TagLibraryInfo;
import org.xml.sax.SAXException;
import com.caucho.config.Config;
import com.caucho.config.ConfigException;
import com.caucho.java.JavaCompilerUtil;
import com.caucho.java.LineMap;
import com.caucho.jsp.cfg.ImplicitTld;
import com.caucho.jsp.cfg.JspConfig;
import com.caucho.jsp.cfg.JspPropertyGroup;
import com.caucho.jsp.java.JavaJspBuilder;
import com.caucho.jsp.java.JspTagSupport;
import com.caucho.jsp.java.TagTaglib;
import com.caucho.server.webapp.WebApp;
import com.caucho.util.L10N;
import com.caucho.vfs.Path;
import com.caucho.vfs.PersistentDependency;
import com.caucho.xml.Xml;
/**
* Compilation interface for JSP pages.
*/
public class JspCompilerInstance {
private static final L10N L = new L10N(JspCompilerInstance.class);
private static final Logger log
= Logger.getLogger(JspCompilerInstance.class.getName());
// The underlying compiler
private JspCompiler _jspCompiler;
// The path to the JSP source
private Path _jspPath;
// The JSP uri (user-name)
private String _uri;
// The JSP class name
private String _className;
private JspPropertyGroup _jspPropertyGroup;
// The builder
private JspBuilder _jspBuilder;
// true for XML parsing
private boolean _isXml;
// true for prototype parsing.
private boolean _isPrototype;
// true for generated source (like XTP)
private boolean _isGeneratedSource;
// The parse state
private ParseState _parseState;
// The tag manager
private ParseTagManager _tagManager;
// The parser
private JspParser _parser;
// The compiled page
private Page _page;
// The generator
private JspGenerator _generator;
private ArrayList _preludeList = new ArrayList();
private ArrayList _codaList = new ArrayList();
private ArrayList _dependList =
new ArrayList();
/**
* Creates a JSP compiler instance.
*/
JspCompilerInstance(JspCompiler compiler)
{
_jspCompiler = compiler;
_isXml = _jspCompiler.isXml();
}
/**
* Sets the builder.
*/
void setJspBuilder(JspBuilder builder)
{
_jspBuilder = builder;
}
/**
* Sets the path.
*/
void setJspPath(Path path)
{
_jspPath = path;
}
/**
* Sets the uri
*/
void setURI(String uri)
{
_uri = uri;
}
/**
* Sets true for xml
*/
void setXML(boolean isXml)
{
_isXml = isXml;
}
/*
* Sets true for generated source
*/
void setGeneratedSource(boolean isGeneratedSource)
{
_isGeneratedSource = isGeneratedSource;
}
/*
* Sets true for generated source
*/
public boolean isGeneratedSource()
{
return _isGeneratedSource;
}
/**
* Sets the class name.
*/
void setClassName(String className)
{
_className = className;
}
/**
* Adds a dependency.
*/
public void addDepend(PersistentDependency depend)
{
_dependList.add(depend);
}
/**
* Adds a dependency.
*/
public void addDependList(ArrayList dependList)
{
if (dependList != null)
_dependList.addAll(dependList);
}
/**
* Returns the jsp configuration.
*/
public JspPropertyGroup getJspPropertyGroup()
{
return _jspPropertyGroup;
}
/**
* Returns true for prototype compilation.
*/
public boolean isPrototype()
{
return _isPrototype;
}
/**
* Set true for prototype compilation.
*/
public void setPrototype(boolean prototype)
{
_isPrototype = prototype;
}
/**
* Initialize the instance.
*/
void init()
throws Exception
{
_parseState = new ParseState();
String uriPwd;
if (_uri != null) {
int p = _uri.lastIndexOf('/');
uriPwd = p <= 0 ? "/" : _uri.substring(0, p + 1);
}
else {
uriPwd = "/";
}
_parseState.setUriPwd(uriPwd);
if (_className == null) {
_className = JavaCompilerUtil.mangleName("jsp/" + _uri);
}
// default to true if ends with x
if (_uri.endsWith("x"))
_parseState.setXml(true);
WebApp webApp = _jspCompiler.getWebApp();
Path appDir = _jspCompiler.getAppDir();
if (appDir == null && webApp != null)
appDir = webApp.getRootDirectory();
if (webApp != null && webApp.hasPre23Config()
&& _parseState.getELIgnoredDefault() == null
&& ! _parseState.isXml()) { // jsp/100a
_parseState.setELIgnoredDefault(true);
}
JspConfig jspConfig = null;
if (jspConfig == null && webApp != null)
jspConfig = (JspConfig) webApp.getExtension("jsp-config");
ArrayList jspList = new ArrayList();
_jspPropertyGroup = null;
if (_jspPropertyGroup == null) {
_jspPropertyGroup = _jspCompiler.getJspPropertyGroup();
if (_jspPropertyGroup != null) {
jspList.add(_jspPropertyGroup);
}
}
if (_jspPropertyGroup == null && webApp != null) {
_jspPropertyGroup = webApp.getJsp();
if (_jspPropertyGroup != null)
jspList.add(_jspPropertyGroup);
}
if (_jspPropertyGroup == null) {
_jspPropertyGroup = _jspCompiler.getJspPropertyGroup();
if (_jspPropertyGroup != null)
jspList.add(_jspPropertyGroup);
}
if (jspConfig != null) {
jspList.addAll(jspConfig.findJspPropertyGroupList(_uri));
if (_parseState.getELIgnoredDefault() == null)
_parseState.setELIgnoredDefault(false);
}
JspResourceManager resourceManager = _jspCompiler.getResourceManager();
if (resourceManager != null) {
}
else if (webApp != null)
resourceManager = new AppResourceManager(webApp);
else {
resourceManager = new AppDirResourceManager(appDir);
}
TagFileManager tagFileManager = _jspCompiler.getTagFileManager();
TaglibManager taglibManager = _jspCompiler.getTaglibManager();
JspPageConfig pageConfig = new JspPageConfig();
for (JspPropertyGroup jspPropertyGroup : jspList) {
ArrayList preludeList = jspPropertyGroup.getIncludePreludeList();
for (int i = 0; preludeList != null && i < preludeList.size(); i++) {
String prelude = preludeList.get(i);
_preludeList.add(prelude);
}
ArrayList codaList = jspPropertyGroup.getIncludeCodaList();
for (int i = 0; codaList != null && i < codaList.size(); i++) {
String coda = codaList.get(i);
_codaList.add(coda);
}
_parseState.setJspPropertyGroup(jspPropertyGroup);
_parseState.setSession(jspPropertyGroup.isSession());
_parseState.setScriptingInvalid(jspPropertyGroup.isScriptingInvalid());
if (jspPropertyGroup.isELIgnored() != null) {
_parseState.setELIgnored(Boolean.TRUE.equals(jspPropertyGroup.isELIgnored()));
}
_parseState.setVelocityEnabled(jspPropertyGroup.isVelocityEnabled());
_parseState.setContentType(jspPropertyGroup.getDefaultContentType());
_parseState.setPageEncoding(jspPropertyGroup.getPageEncoding());
if (Boolean.TRUE.equals(jspPropertyGroup.isXml()))
_parseState.setXml(true);
if (Boolean.FALSE.equals(jspPropertyGroup.isXml())) {
_parseState.setXml(false);
_parseState.setForbidXml(true);
}
if (jspPropertyGroup.getPageEncoding() != null) {
try {
_parseState.setPageEncoding(jspPropertyGroup.getPageEncoding());
} catch (JspParseException e) {
}
}
pageConfig.setStaticEncoding(jspPropertyGroup.isStaticEncoding());
_parseState.setTrimWhitespace(jspPropertyGroup.isTrimDirectiveWhitespaces());
_parseState.setDeferredSyntaxAllowedAsLiteral(jspPropertyGroup.isDeferredSyntaxAllowedAsLiteral());
if (jspPropertyGroup.getTldFileSet() != null)
taglibManager.setTldFileSet(jspPropertyGroup.getTldFileSet());
}
if (webApp != null && webApp.getJsp() != null) {
_parseState.setRecycleTags(webApp.getJsp().isRecycleTags());
}
_parseState.setResourceManager(resourceManager);
LineMap lineMap = null;
_tagManager = new ParseTagManager(resourceManager,
taglibManager,
tagFileManager);
_jspBuilder = new JavaJspBuilder();
_jspBuilder.setParseState(_parseState);
_jspBuilder.setJspCompiler(_jspCompiler);
_jspBuilder.setJspPropertyGroup(_jspPropertyGroup);
_jspBuilder.setTagManager(_tagManager);
_jspBuilder.setPageConfig(pageConfig);
_jspBuilder.setPrototype(_isPrototype);
_parser = new JspParser();
_parser.setJspBuilder(_jspBuilder);
_parser.setParseState(_parseState);
_parser.setTagManager(_tagManager);
_jspBuilder.setJspParser(_parser);
/*
for (int i = 0; i < _preludeList.size(); i++)
_parser.addPrelude(_preludeList.get(i));
for (int i = 0; i < _codaList.size(); i++)
_parser.addCoda(_codaList.get(i));
*/
}
public Page compile()
throws Exception
{
LineMap lineMap = null;
if (_page != null)
throw new IllegalStateException("JspCompilerInstance cannot be reused");
try {
JspGenerator generator = generate();
lineMap = generator.getLineMap();
String encoding = _parseState.getCharEncoding();
_jspCompiler.compilePending();
_generator = generator;
if (! generator.isStatic()) {
compileJava(_jspPath, _className, lineMap, encoding);
}
return load();
} catch (JspParseException e) {
e.setLineMap(lineMap);
e.setErrorPage(_parseState.getErrorPage());
throw e;
} catch (SAXException e) {
if (e.getCause() instanceof JspParseException) {
JspParseException subE = (JspParseException) e.getCause();
subE.setLineMap(lineMap);
subE.setErrorPage(_parseState.getErrorPage());
throw subE;
}
else {
JspParseException exn = new JspParseException(e);
exn.setErrorPage(_parseState.getErrorPage());
exn.setLineMap(lineMap);
throw exn;
}
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
JspParseException exn = new JspParseException(e);
exn.setLineMap(lineMap);
exn.setErrorPage(_parseState.getErrorPage());
throw exn;
} catch (Throwable e) {
JspParseException exn = new JspParseException(e);
exn.setLineMap(lineMap);
exn.setErrorPage(_parseState.getErrorPage());
throw exn;
}
}
public Page load()
throws Exception
{
LineMap lineMap = _generator.getLineMap();
try {
boolean isAutoCompile = true;
if (_jspPropertyGroup != null) {
isAutoCompile = _jspPropertyGroup.isAutoCompile();
}
Page page;
if (! _generator.isStatic()) {
page = _jspCompiler.loadPage(_className, isAutoCompile);
}
else {
page = _jspCompiler.loadStatic(_className,
_parseState.isOptionalSession());
page._caucho_addDepend(_generator.getDependList());
page._caucho_setContentType(_parseState.getContentType());
}
return page;
} catch (Throwable e) {
JspParseException exn = new JspParseException(e);
exn.setLineMap(lineMap);
exn.setErrorPage(_parseState.getErrorPage());
throw exn;
}
}
public JspGenerator generate()
throws Exception
{
if (_page != null)
throw new IllegalStateException("JspCompilerInstance cannot be reused");
parse();
try {
JspGenerator generator = _jspBuilder.getGenerator();
generator.setJspCompilerInstance(this);
for (int i = 0; i < _dependList.size(); i++)
generator.addDepend(_dependList.get(i));
generator.validate();
generator.generate(_jspPath, _className);
return generator;
} catch (IOException e) {
JspParseException exn = new JspParseException(e);
exn.setErrorPage(_parseState.getErrorPage());
throw exn;
}
}
public void parse()
throws Exception
{
boolean isXml = _parseState.isXml();
boolean isForbidXml = _parseState.isForbidXml();
ParseState parseState = _parser.getParseState();
try {
_parser.getParseState().setBuilder(_jspBuilder);
for (String prelude : _preludeList) {
parseState.setXml(false);
parseState.setForbidXml(false);
_parser.parse(parseState.getResourceManager().resolvePath(prelude),
prelude);
}
_parser.getParseState().setXml(isXml);
_parser.getParseState().setForbidXml(isForbidXml);
if (isXml) {
if (_parseState.getELIgnoredDefault() == null)
_parseState.setELIgnoredDefault(false);
Xml xml = new Xml();
_parseState.setXml(xml);
xml.setContentHandler(new JspContentHandler(_jspBuilder));
_jspPath.setUserPath(_uri);
xml.setNamespaceAware(true);
xml.setDtdValidating(true);
xml.parse(_jspPath);
}
else {
WebApp app = _jspCompiler.getWebApp();
// jsp/0135
if (app != null && app.hasPre23Config()) {
if (_parseState.getELIgnoredDefault() == null)
_parseState.setELIgnoredDefault(true);
}
_parser.parse(_jspPath, _uri);
}
for (String coda : _codaList) {
parseState.setXml(false);
parseState.setForbidXml(false);
_parser.parse(parseState.getResourceManager().resolvePath(coda),
coda);
}
} catch (JspParseException e) {
e.setErrorPage(_parseState.getErrorPage());
throw e;
} catch (SAXException e) {
if (e.getCause() instanceof JspParseException) {
JspParseException subE = (JspParseException) e.getCause();
subE.setErrorPage(_parseState.getErrorPage());
throw subE;
}
else {
JspParseException exn = new JspParseException(e);
exn.setErrorPage(_parseState.getErrorPage());
throw exn;
}
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
JspParseException exn = new JspParseException(e);
exn.setErrorPage(_parseState.getErrorPage());
throw exn;
}
}
public TagInfo compileTag(TagTaglib taglib)
throws Exception
{
TagInfo preloadTag = preloadTag(taglib);
if (preloadTag != null)
return preloadTag;
return generateTag(taglib);
}
private TagInfo preloadTag(TagLibraryInfo taglib)
{
try {
JspTagSupport tag = (JspTagSupport) _jspCompiler.loadClass(_className, true);
if (tag == null)
return null;
tag.init(_jspCompiler.getAppDir());
if (tag._caucho_isModified())
return null;
return tag._caucho_getTagInfo(taglib);
} catch (Throwable e) {
return null;
}
}
private TagInfo generateTag(TagTaglib taglib)
throws Exception
{
LineMap lineMap = null;
if (_page != null)
throw new IllegalStateException("JspCompilerInstance cannot be reused");
try {
boolean isXml = _isXml;
if (_jspPropertyGroup != null && ! isXml
&& _jspPropertyGroup.isXml() != null)
isXml = Boolean.TRUE.equals(_jspPropertyGroup.isXml());
if (_jspPropertyGroup != null
&& Boolean.FALSE.equals(_jspPropertyGroup.isXml()))
_parseState.setForbidXml(true);
_parseState.setXml(isXml);
if (_jspCompiler.addTag(_className)) {
_isPrototype = true;
_jspBuilder.setPrototype(true);
}
_parseState.setTag(true);
_isXml = isXml;
Path implicitTld = _jspPath.lookup(_jspPath.getParent() + "/implicit.tld");
// jsp/10h4
taglib.setJspVersion("2.0");
if (implicitTld.canRead()) {
Config config = new Config();
ImplicitTld tldTaglib = new ImplicitTld();
config.configure(tldTaglib, implicitTld);
if (tldTaglib.getJspVersion() != null
&& tldTaglib.getJspVersion().compareTo("2.0") < 0)
throw new ConfigException(L.l("'{0}' must have a jsp-version 2.0 or greater",
implicitTld));
taglib.setJspVersion(tldTaglib.getJspVersion());
}
if (taglib.getRequiredVersion().compareTo("2.1") < 0) {
_parseState.setJspVersion("2.0");
_parseState.setDeferredSyntaxAllowedAsLiteral(true);
}
if (isXml) {
_parseState.setELIgnoredDefault(false);
Xml xml = new Xml();
_parseState.setXml(xml);
xml.setContentHandler(new JspContentHandler(_jspBuilder));
_jspPath.setUserPath(_uri);
xml.setNamespaceAware(true);
xml.setDtdValidating(true);
xml.parse(_jspPath);
}
else {
_parser.parseTag(_jspPath, _uri);
}
_generator = _jspBuilder.getGenerator();
if (_isPrototype) {
return _generator.generateTagInfo(_className, taglib);
}
_generator.validate();
_generator.generate(_jspPath, _className);
if (_jspCompiler.hasRecursiveCompile()) {
_jspCompiler.addPending(this);
return _generator.generateTagInfo(_className, taglib);
}
return completeTag(taglib);
} catch (JspParseException e) {
e.setLineMap(lineMap);
e.setErrorPage(_parseState.getErrorPage());
throw e;
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
JspParseException exn = new JspParseException(e);
exn.setErrorPage(_parseState.getErrorPage());
exn.setLineMap(lineMap);
throw exn;
}
}
TagInfo completeTag()
throws Exception
{
return completeTag(new TagTaglib("x", "uri"));
}
TagInfo completeTag(TagLibraryInfo taglib)
throws Exception
{
LineMap lineMap = null;
try {
lineMap = _generator.getLineMap();
String encoding = _parseState.getCharEncoding();
compileJava(_jspPath, _className, lineMap, encoding);
JspTagSupport tag = (JspTagSupport) _jspCompiler.loadClass(_className, true);
tag.init(_jspCompiler.getAppDir());
return tag._caucho_getTagInfo(taglib);
// Page page = _jspCompiler.loadClass(_className);
} catch (JspParseException e) {
e.setLineMap(lineMap);
e.setErrorPage(_parseState.getErrorPage());
throw e;
} catch (FileNotFoundException e) {
throw e;
} catch (IOException e) {
JspParseException exn = new JspParseException(e);
exn.setErrorPage(_parseState.getErrorPage());
exn.setLineMap(lineMap);
throw exn;
} catch (Throwable e) {
JspParseException exn = new JspParseException(e);
exn.setErrorPage(_parseState.getErrorPage());
exn.setLineMap(lineMap);
throw exn;
}
}
private void compileJava(Path path, String className,
LineMap lineMap, String charEncoding)
throws Exception
{
JavaCompilerUtil compiler = JavaCompilerUtil.create(null);
compiler.setClassDir(_jspCompiler.getClassDir());
// compiler.setEncoding(charEncoding);
String fileName = className.replace('.', '/') + ".java";
compiler.compile(fileName, lineMap);
/*
boolean remove = true;
try {
compiler.compile(fileName, lineMap);
remove = false;
} finally {
if (remove)
Vfs.lookup(fileName).remove();
}
*/
Path classDir = _jspCompiler.getClassDir();
Path classPath = classDir.lookup(className.replace('.', '/') + ".class");
Path smapPath = classDir.lookup(fileName + ".smap");
// jsp/18p1
// compiler.mergeSmap(classPath, smapPath);
}
private void readSmap(ClassLoader loader, String className)
{
if (loader == null)
return;
String smapName = className.replace('.', '/') + ".java.smap";
InputStream is = null;
try {
is = loader.getResourceAsStream(smapName);
} catch (Exception e) {
log.log(Level.FINE, e.toString(), e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy