com.caucho.xsl.AbstractStylesheetFactory 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.xsl;
import com.caucho.java.JavaCompilerUtil;
import com.caucho.loader.DynamicClassLoader;
import com.caucho.loader.EnvironmentLocal;
import com.caucho.loader.SimpleLoader;
import com.caucho.server.util.CauchoSystem;
import com.caucho.util.Base64;
import com.caucho.util.CharBuffer;
import com.caucho.util.L10N;
import com.caucho.util.LruCache;
import com.caucho.vfs.Crc64Stream;
import com.caucho.vfs.Path;
import com.caucho.vfs.MergePath;
import com.caucho.vfs.ReadStream;
import com.caucho.vfs.Vfs;
import com.caucho.vfs.WriteStream;
import com.caucho.xml.*;
import com.caucho.xpath.Expr;
import com.caucho.xpath.XPath;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Node;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLFilter;
import org.xml.sax.XMLReader;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.URIResolver;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TemplatesHandler;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.lang.ref.SoftReference;
import java.util.Iterator;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Abstract factory for creating stylesheets.
*/
abstract public class AbstractStylesheetFactory
extends SAXTransformerFactory {
static final Logger log
= Logger.getLogger(AbstractStylesheetFactory.class.getName());
static final L10N L = new L10N(AbstractStylesheetFactory.class);
private static
EnvironmentLocal>> _stylesheetCache =
new EnvironmentLocal>>();
private URIResolver _uriResolver;
private ErrorListener _errorListener;
private String _systemId;
private Path _workPath;
private Path _stylePath;
private ClassLoader _loader;
private String _className;
private boolean _isAutoCompile = true;
private boolean _loadPrecompiledStylesheet = true;
protected AbstractStylesheetFactory()
{
}
/**
* Returns an implementation-specific attribute.
*
* @param name the attribute name
*/
public Object getAttribute(String name)
{
return null;
}
/**
* Sets an implementation-specific attribute.
*
* @param name the attribute name
* @param value the attribute value
*/
public void setAttribute(String name, Object value)
{
}
/**
* Returns an implementation-specific feature.
*
* @param name the feature name
*/
public boolean getFeature(String name)
{
if (name.equals(SAXTransformerFactory.FEATURE) ||
name.equals(SAXTransformerFactory.FEATURE_XMLFILTER) ||
name.equals(DOMResult.FEATURE) ||
name.equals(DOMSource.FEATURE) ||
name.equals(SAXResult.FEATURE) ||
name.equals(SAXSource.FEATURE) ||
name.equals(StreamResult.FEATURE) ||
name.equals(StreamSource.FEATURE))
return true;
else
return false;
}
/**
* Sets an implementation-specific feature
*
* @param name the feature name
* @param value the feature value
*/
public void setFeature(String name, boolean value)
{
}
/**
* Returns the URI to filename resolver.
*/
public URIResolver getURIResolver()
{
return _uriResolver;
}
/**
* Sets the URI to filename resolver.
*/
public void setURIResolver(URIResolver uriResolver)
{
_uriResolver = uriResolver;
}
/**
* Returns the error listener.
*/
public ErrorListener getErrorListener()
{
return _errorListener;
}
/**
* Sets the error listener.
*/
public void setErrorListener(ErrorListener errorListener)
{
_errorListener = errorListener;
}
public String getSystemId()
{
return _systemId;
}
public void setSystemId(String systemId)
{
_systemId = systemId;
}
/**
* Sets the search path for stylesheets. Generally applications will use
* MergePath to create their search path.
*
* @param path path containing stylesheets.
*/
public void setStylePath(Path path)
{
_stylePath = path;
}
/**
* Returns the stylesheet search path.
*/
public Path getStylePath()
{
if (_stylePath != null)
return _stylePath;
else
return getSearchPath();
}
/**
* Sets the search path for stylesheets. Generally applications will use
* MergePath to create their search path.
*
* @param path path containing stylesheets.
*/
public void setSearchPath(Path path)
{
_stylePath = path;
}
/**
* Returns the stylesheet search path.
*/
public Path getSearchPath()
{
if (_stylePath != null)
return _stylePath;
else
return Vfs.getPwd();
}
/**
* Sets the working directory.
*/
public void setWorkPath(Path path)
{
_workPath = path;
}
/**
* Gets the working directory.
*/
public Path getWorkPath()
{
if (_workPath != null)
return _workPath;
else
return CauchoSystem.getWorkPath();
}
public void setClassName(String className)
{
_className = className;
}
public String getClassName()
{
return _className;
}
/**
* Sets the classloader for the stylesheet.
*
* @param loader the new loader.
*/
public void setClassLoader(ClassLoader loader)
{
_loader = loader;
}
/**
* Gets the classloader for the stylesheet.
*/
public ClassLoader getClassLoader()
{
return _loader;
}
/**
* Returns true if precompiled stylesheets should be loaded.
*/
public boolean getLoadPrecompiledStylesheet()
{
return _loadPrecompiledStylesheet;
}
/**
* Returns true if precompiled stylesheets should be loaded.
*/
public void setLoadPrecompiledStylesheet(boolean preload)
{
_loadPrecompiledStylesheet = preload;
}
/**
* Returns true if the stylesheet should be automatically compiled.
*/
public boolean isAutoCompile()
{
return _isAutoCompile;
}
/**
* Returns true if precompiled stylesheets should be loaded.
*/
public void setAutoCompile(boolean autoCompile)
{
_isAutoCompile = autoCompile;
}
/**
* Returns the stylesheet source object associated with the given
* XML document.
*
* @param source the XML document which needs a stylesheet.
* @param media the media attribute for the stylesheet
* @param title the title attribute for the stylesheet
* @param charset the character encoding for the stylesheet result.
*/
public Source getAssociatedStylesheet(Source source,
String media,
String title,
String charset)
throws TransformerConfigurationException
{
try {
XmlStylesheetReader reader = new XmlStylesheetReader();
parseSAX(source, reader);
String href = reader.getAssociatedStylesheet(media, title, charset);
if (href == null)
return null;
String base = source.getSystemId();
return getSource(href, base);
} catch (Exception e) {
throw new TransformerConfigurationException(e);
}
}
/**
* Opens a relative path.
*/
private Source getSource(String href, String base)
throws Exception
{
Path subpath;
if (href == null)
href = "";
if (base == null)
base = "/";
if (_uriResolver != null) {
if (href.startsWith("/") || base.equals("/"))
subpath = getSearchPath().lookup(href);
else {
subpath = getSearchPath().lookup(base).getParent().lookup(href);
}
Source source = _uriResolver.resolve(href, base);
if (source != null) {
if (source.getSystemId() == null)
source.setSystemId(subpath.getURL());
return source;
}
}
if (href.startsWith("/") || base.equals("/"))
subpath = getSearchPath().lookup(href);
else {
if (base.startsWith("file:"))
base = base.substring(5);
subpath = getSearchPath().lookup(base).getParent().lookup(href);
}
return new StreamSource(subpath.getURL());
}
private void parseSAX(Source source, ContentHandler handler)
throws TransformerConfigurationException
{
try {
if (source instanceof SAXSource) {
SAXSource saxSource = (SAXSource) source;
XMLReader reader = saxSource.getXMLReader();
InputSource inputSource = saxSource.getInputSource();
reader.setContentHandler(handler);
reader.parse(inputSource);
}
else if (source instanceof StreamSource) {
XmlParser parser = new Xml();
parser.setContentHandler(handler);
ReadStream rs = openPath(source);
try {
parser.parse(rs);
} finally {
rs.close();
}
}
else if (source instanceof DOMSource) {
DOMSource domSource = (DOMSource) source;
Node node = domSource.getNode();
XmlUtil.toSAX(node, handler);
}
} catch (Exception e) {
throw new TransformerConfigurationException(e);
}
}
/**
* Create a transformer from an input stream.
*
* @param source the source stream
*
* @return the compiled stylesheet
*/
public javax.xml.transform.Transformer newTransformer(Source source)
throws TransformerConfigurationException
{
Templates templates = newTemplates(source);
return templates.newTransformer();
}
/**
* Create an identity transformer.
*
* @return the compiled stylesheet
*/
public javax.xml.transform.Transformer newTransformer()
throws TransformerConfigurationException
{
return new TransformerImpl(new IdentityStylesheet());
}
/**
* Creates a new stylesheet from an XML document.
*/
public StylesheetImpl newStylesheet(Document xsl)
throws Exception
{
return (StylesheetImpl) generate(xsl, null);
}
/**
* Create a new stylesheet from a reader.
*/
public StylesheetImpl newStylesheet(Reader reader)
throws Exception
{
ReadStream rs = Vfs.openRead(reader);
return (StylesheetImpl) generate(parseXSL(rs), rs.getPath());
}
/**
* Create a new stylesheet from an input stream.
*/
public StylesheetImpl newStylesheet(InputStream is)
throws Exception
{
ReadStream rs = Vfs.openRead(is);
return (StylesheetImpl) generate(parseXSL(rs), rs.getPath());
}
/**
* Loads a stylesheet from a named file
*
* @param systemId the URL of the file
*/
public StylesheetImpl newStylesheet(String systemId)
throws Exception
{
StylesheetImpl stylesheet = loadPrecompiledStylesheet(systemId, systemId);
if (stylesheet != null)
return stylesheet;
synchronized (AbstractStylesheetFactory.class) {
stylesheet = loadPrecompiledStylesheet(systemId, systemId);
if (stylesheet != null)
return stylesheet;
ReadStream is;
if (_stylePath != null)
is = _stylePath.lookup(systemId).openRead();
else
is = Vfs.lookup(systemId).openRead();
try {
return newStylesheet(is);
} finally {
if (is != null)
is.close();
}
}
}
public StylesheetImpl newStylesheet(Path path)
throws Exception
{
StylesheetImpl stylesheet = loadPrecompiledStylesheet(path.getFullPath(),
path.getUserPath());
if (stylesheet != null)
return stylesheet;
synchronized (AbstractStylesheetFactory.class) {
stylesheet = loadPrecompiledStylesheet(path.getFullPath(),
path.getUserPath());
if (stylesheet != null)
return stylesheet;
Path oldStylePath = _stylePath;
if (_stylePath == null)
_stylePath = path.getParent();
InputStream is = null;
try {
is = path.openRead();
return newStylesheet(is);
} finally {
_stylePath = oldStylePath;
if (is != null)
is.close();
}
}
}
/**
* Create a compiled stylesheet from an input stream.
*
* @param source the source stream
*
* @return the compiled stylesheet
*/
public Templates newTemplates(Source source)
throws TransformerConfigurationException
{
String systemId = source.getSystemId();
try {
if (systemId != null) {
StylesheetImpl stylesheet = loadPrecompiledStylesheet(systemId,
systemId);
if (stylesheet != null)
return stylesheet;
}
if (source instanceof DOMSource) {
Node node = ((DOMSource) source).getNode();
return generateFromNode(node, systemId);
}
else if (source instanceof SAXSource) {
SAXSource saxSource = (SAXSource) source;
XMLReader reader = saxSource.getXMLReader();
InputSource inputSource = saxSource.getInputSource();
Document doc = new QDocument();
DOMBuilder builder = new DOMBuilder();
builder.init(doc);
reader.setContentHandler(builder);
reader.parse(inputSource);
return generateFromNode(doc, systemId);
}
ReadStream rs = openPath(source);
try {
Path path = rs.getPath();
Document doc = parseXSL(rs);
if (systemId != null) {
String mangledName = getMangledName(systemId);
Path genPath = getWorkPath().lookup(mangledName);
genPath.setUserPath(systemId);
return generate(doc, genPath);
}
else
return generateFromNode(doc, null);
} finally {
if (rs != null)
rs.close();
}
} catch (TransformerConfigurationException e) {
throw e;
} catch (Exception e) {
throw new XslParseException(e);
}
}
private Templates generateFromNode(Node node, String systemId)
throws IOException, TransformerConfigurationException
{
Path tempPath = writeTempFile(node);
String tempId = tempPath.getTail();
StylesheetImpl stylesheet = loadPrecompiledStylesheet(tempId,
tempId,
false);
if (systemId != null)
tempPath.setUserPath(systemId);
if (stylesheet != null)
return stylesheet;
return generate(node, tempPath);
}
private Path writeTempFile(Node node)
throws IOException
{
Path workDir = CauchoSystem.getWorkPath().lookup("_xsl");
workDir.mkdirs();
// Path temp = workDir.createTempFile("tmp", "xsl");
WriteStream os = Vfs.lookup("null:").openWrite();
Crc64Stream crcStream = new Crc64Stream(os.getSource());
os.init(crcStream);
try {
XmlPrinter printer = new XmlPrinter(os);
printer.printNode(node);
} finally {
os.close();
}
long crc = crcStream.getCRC();
CharBuffer cb = new CharBuffer();
Base64.encode(cb, crc);
String crcValue = cb.toString().replace('/', '-');
Path xslPath = workDir.lookup(crcValue + ".xsl");
// temp.renameTo(xslPath);
return xslPath;
}
/**
* Create a new transformer handler.
*/
public TransformerHandler newTransformerHandler()
throws TransformerConfigurationException
{
return newTransformerHandler(new StylesheetImpl());
}
/**
* Create a new transformer handler based on a source.
*/
public TransformerHandler newTransformerHandler(Source source)
throws TransformerConfigurationException
{
return newTransformerHandler(newTemplates(source));
}
/**
* Create a new transformer handler based on a stylesheet.
*/
public TransformerHandler newTransformerHandler(Templates templates)
throws TransformerConfigurationException
{
return new TransformerHandlerImpl(templates.newTransformer());
}
/**
* Returns a templates handler.
*
* @param source the source file
*/
public TemplatesHandler newTemplatesHandler()
throws TransformerConfigurationException
{
return new TemplatesHandlerImpl(this);
}
/**
* Returns an XML filter from the transformer.
*
* @param source the source file
*/
public XMLFilter newXMLFilter(Source source)
throws TransformerConfigurationException
{
Templates templates = newTemplates(source);
return newXMLFilter(templates);
}
/**
* Returns an XML filter from the transformer.
*
* @param source the source file
*/
public XMLFilter newXMLFilter(Templates templates)
throws TransformerConfigurationException
{
return new SAXFilterImpl((TransformerImpl) templates.newTransformer());
}
/**
* Parses a stylesheet from the source.
*/
protected Node parseStylesheet(Source source)
throws TransformerConfigurationException
{
if (source instanceof DOMSource)
return ((DOMSource) source).getNode();
else if (source instanceof StreamSource) {
InputStream is = ((StreamSource) source).getInputStream();
ReadStream rs = null;
try {
rs = Vfs.openRead(is);
return parseXSL(rs);
} catch (Exception e) {
throw new TransformerConfigurationException(e);
} finally {
if (rs != null)
rs.close();
}
}
else
return null;
}
/**
* Convenience class to create a compiled stylesheet.
*
* @param node DOM source for the stylesheet.
*
* @return a compiled stylesheet
*/
public javax.xml.transform.Templates newTemplates(Node node)
throws TransformerConfigurationException
{
Document doc = node.getOwnerDocument();
if (node instanceof Document)
doc = (Document) node;
DocumentType dtd = doc.getDoctype();
if (dtd != null && dtd.getSystemId() != null)
return generate(node, getSearchPath().lookup(dtd.getSystemId()));
else if (doc instanceof CauchoDocument) {
String systemId = ((CauchoDocument) doc).getFilename();
return generate(node, getSearchPath().lookup(systemId));
}
else
return generate(node, null);
}
/**
* Convenience class to create a compiled stylesheet.
*
* @param systemId source path for the stylesheet.
*
* @return a compiled stylesheet
*/
public javax.xml.transform.Templates newTemplates(String systemId)
throws TransformerConfigurationException
{
StylesheetImpl stylesheet = loadPrecompiledStylesheet(systemId, systemId);
if (stylesheet != null)
return stylesheet;
else if (systemId == null)
return generate(new QDocument(), null);
Path path = getSearchPath().lookup(systemId);
try {
ReadStream is = path.openRead();
Document doc;
try {
doc = parseXSL(is);
} finally {
is.close();
}
return generate(doc, path);
} catch (TransformerConfigurationException e) {
throw e;
} catch (IOException e) {
throw new TransformerConfigurationExceptionWrapper(e);
} catch (Exception e) {
throw new TransformerConfigurationExceptionWrapper(e);
}
}
/**
* Opens a relative path.
*/
ReadStream openPath(String href, String base)
throws TransformerException, IOException
{
if (_uriResolver != null) {
Source source = _uriResolver.resolve(href, base);
if (source != null)
return openPath(source);
}
if (href.startsWith("/") || base.equals("/"))
return getSearchPath().lookup(href).openRead();
else {
Path path = getSearchPath().lookup(base).getParent().lookup(href);
if (path.exists())
return path.openRead();
else
return getSearchPath().lookup(href).openRead();
}
}
/**
* Opens a path based on a Source.
*/
ReadStream openPath(Source source)
throws TransformerException, IOException
{
String systemId = source.getSystemId();
Path path;
if (systemId != null)
path = getSearchPath().lookup(systemId);
else
path = getSearchPath().lookup("anonymous.xsl");
if (source instanceof StreamSource) {
StreamSource stream = (StreamSource) source;
InputStream is = stream.getInputStream();
if (is instanceof ReadStream) {
ReadStream rs = (ReadStream) is;
rs.setPath(path);
return rs;
}
else if (is != null) {
ReadStream rs = Vfs.openRead(is);
rs.setPath(path);
return rs;
}
Reader reader = stream.getReader();
if (reader != null) {
ReadStream rs = Vfs.openRead(reader);
rs.setPath(path);
return rs;
}
}
if (systemId != null)
return getSearchPath().lookup(systemId).openRead();
throw new TransformerException("bad source " + source);
}
Path lookupPath(String base, String href)
throws TransformerException
{
if (_uriResolver != null) {
Source source = _uriResolver.resolve(href, base);
if (source != null) {
String systemId = source.getSystemId();
if (systemId != null)
return getSearchPath().lookup(systemId);
}
}
return getSearchPath().lookup(base).lookup(href);
}
/**
* Convenience class to create a transformer instance.
*
* @param xsl DOM source for the stylesheet.
*
* @return a transformer instance.
*/
public javax.xml.transform.Transformer newTransformer(Document xsl)
throws TransformerConfigurationException
{
return newTemplates(xsl).newTransformer();
}
/**
* Convenience class to transform a node.
*
* @param xsl DOM containing the parsed xsl.
* @param xml DOM document node.
* @param out output stream destination.
*/
public void transform(Document xsl, Node xml, OutputStream out)
throws Exception
{
TransformerImpl transformer = (TransformerImpl) newTransformer(xsl);
transformer.transform(xml, out);
}
/**
* Convenience class to transform a node.
*
* @param xsl path name to the xsl file.
* @param xml dom source document.
* @param out output stream destination.
*/
public void transform(String xsl, Node xml, OutputStream out)
throws Exception
{
TransformerImpl transformer;
transformer = (TransformerImpl) newTemplates(xsl).newTransformer();
transformer.transform(xml, out);
}
/**
* Parses the XSL into a DOM document.
*
* @param rs the input stream.
*/
abstract protected Document parseXSL(ReadStream rs)
throws TransformerConfigurationException;
/**
* Generates a compiled stylesheet from a parsed XSL document.
*
* @param xsl the parsed xsl document.
* @param path the path to the document.
*/
Templates generate(Node xsl, Path path)
throws TransformerConfigurationException
{
log.fine("Generating XSL from " + path);
// The code generation needs a static lock because the
// application might have a separate factory object
// for each thread. The static lock protects the code generation
// from overwriting its own code.
synchronized (AbstractStylesheetFactory.class) {
Generator gen = null;
try {
if (path == null && xsl != null) {
Document doc = xsl.getOwnerDocument();
if (doc == null && xsl instanceof Document)
doc = (Document) xsl;
DocumentType dtd = doc.getDoctype();
String systemId = null;
if (dtd != null)
systemId = dtd.getSystemId();
if (systemId != null)
path = getStylePath().lookup(systemId);
}
if (path == null && xsl instanceof CauchoNode) {
String filename = ((CauchoNode) xsl).getFilename();
if (filename != null)
path = getStylePath().lookup(filename);
}
if (path == null)
path = getStylePath().lookup("anonymous.xsl");
Path stylePath = path.getParent();
Expr expr = XPath.parseExpr("//xtp:directive.page/@language");
String language = expr.evalString(xsl);
String userName = path.getUserPath();
String mangledName = getMangledName(userName);
String encoding = XPath.evalString("//xsl:output/@encoding", xsl);
if (encoding != null && encoding.equals(""))
encoding = null;
if (language == null || language.equals("") || language.equals("java")) {
language = "java";
gen = new JavaGenerator(this, mangledName, encoding);
}
else
throw new XslParseException(L.l("unsupported language `{0}'",
language));
gen.setPath(path);
Iterator iter = XPath.select("//xtp:directive.page/@*", xsl);
while (iter.hasNext()) {
Attr attr = (Attr) iter.next();
String name = attr.getNodeName();
String value = attr.getNodeValue();
if (name.equals("errorPage"))
gen.setErrorPage(value);
else if (name.equals("import"))
gen.addImport(value);
else if (name.equals("contentType"))
gen.setContentType(value);
else if (name.equals("language")) {
if (! language.equalsIgnoreCase(value))
throw new XslParseException(L.l("mismatched language `{0}'",
value));
}
else if (name.equals("xml:space")) {
}
else
throw new XslParseException(L.l("unknown directive `{0}'",
name));
}
StylesheetImpl stylesheet = gen.generate(xsl);
gen = null;
stylesheet.init(path);
// XXX: why was this here? stylesheet.init(getStylePath());
stylesheet.setURIResolver(_uriResolver);
return stylesheet;
} catch (TransformerConfigurationException e) {
throw e;
} catch (Exception e) {
throw new XslParseException(e);
} finally {
try {
if (gen != null)
gen.close();
} catch (IOException e) {
}
}
}
}
/**
* Returns the mangled classname for the stylesheet. If getClassName()
* is not null, it will be used as the mangled name.
*
* @param userName the user specified name for the stylesheet.
*
* @return a valid Java classname for the generated stylesheet.
*/
private String getMangledName(String userName)
{
String name = null;
if (userName == null || userName.equals("anonymous.xsl") ||
userName.equals("string") || userName.equals("stream")) {
userName = "x" + (new Random().nextInt() & 0x3ff) + ".xsl";
}
if (getClassName() == null)
name = userName;
else
name = getClassName();
if (name.startsWith("/"))
name = "xsl" + name;
else
name = "xsl/" + name;
return JavaCompilerUtil.mangleName(name);
}
/**
* Returns existing compiled Templates if it exists.
*
* @param systemId source path for the stylesheet.
*
* @return a compiled stylesheet
*/
StylesheetImpl loadPrecompiledStylesheet(String systemId,
String userId)
{
return loadPrecompiledStylesheet(systemId, userId, _isAutoCompile);
}
/**
* Returns existing compiled Templates if it exists.
*
* @param systemId source path for the stylesheet.
*
* @return a compiled stylesheet
*/
StylesheetImpl loadPrecompiledStylesheet(String systemId,
String userId,
boolean checkModified)
{
if (! _loadPrecompiledStylesheet)
return null;
try {
// look for compiled template base on SystemID
StylesheetImpl stylesheet = loadStylesheet(systemId,
getMangledName(userId));
if (stylesheet == null)
return null;
stylesheet.setURIResolver(_uriResolver);
// and check if it's modified or not
if (! checkModified || ! stylesheet.isModified()) {
stylesheet.setURIResolver(_uriResolver);
return stylesheet;
}
} catch (Throwable e) {
log.log(Level.FINER, e.toString(), e);
}
return null;
}
/**
* Loads the compiled stylesheet .class file
*
* @param className the mangled classname for the stylesheet
*/
protected StylesheetImpl loadStylesheet(String systemId, String className)
throws Exception
{
LruCache> cache;
ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
cache = _stylesheetCache.getLevel(parentLoader);
if (cache == null) {
cache = new LruCache>(256);
_stylesheetCache.set(cache, parentLoader);
}
SoftReference stylesheetRef;
stylesheetRef = cache.get(className);
StylesheetImpl stylesheet = null;
if (stylesheetRef != null)
stylesheet = stylesheetRef.get();
try {
if (stylesheet != null && ! stylesheet.isModified())
return stylesheet;
} catch (Throwable e) {
log.log(Level.FINER, e.toString(), e);
}
Path classPath = getWorkPath().lookup(className.replace('.', '/') + ".class");
if (! classPath.canRead())
throw new ClassNotFoundException("can't find compiled XSL `" + className + "'");
DynamicClassLoader loader;
loader = SimpleLoader.create(parentLoader, getWorkPath(), className);
Class cl = null;
// If the loading fails, remove the class because it may be corrupted
try {
cl = CauchoSystem.loadClass(className, false, loader);
} catch (Error e) {
try {
classPath.remove();
} catch (IOException e1) {
log.log(Level.FINE, e1.toString(), e1);
}
throw e;
}
stylesheet = (StylesheetImpl) cl.newInstance();
Path path;
path = getSearchPath().lookup("").lookup(systemId);
/*
try {
} catch (TransformerException e) {
log.log(Level.FINE, e.toString(), e);
path = Vfs.lookup(systemId);
}
*/
// stylesheet.init(path);
stylesheet.init(getStylePath());
stylesheet.setURIResolver(_uriResolver);
stylesheetRef = new SoftReference(stylesheet);
cache.put(className, stylesheetRef);
return stylesheet;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy