xtppage.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 843 行 · 第 1/2 页
JAVA
843 行
/* * Copyright (c) 1998-2008 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 com.caucho.java.JavaCompiler;import com.caucho.java.LineMap;import com.caucho.log.Log;import com.caucho.server.connection.CauchoRequest;import com.caucho.server.connection.CauchoResponse;import com.caucho.server.connection.RequestAdapter;import com.caucho.server.connection.ResponseAdapter;import com.caucho.server.dispatch.ServletConfigImpl;import com.caucho.server.webapp.WebApp;import com.caucho.util.Base64;import com.caucho.util.CharBuffer;import com.caucho.util.RegistryException;import com.caucho.vfs.Depend;import com.caucho.vfs.Path;import com.caucho.vfs.PersistentDependency;import com.caucho.vfs.ReadStream;import com.caucho.vfs.Vfs;import com.caucho.vfs.WriteStream;import com.caucho.xml.CauchoDocument;import com.caucho.xml.Html;import com.caucho.xml.Xml;import com.caucho.xml.XmlParser;import com.caucho.xml.XmlUtil;import com.caucho.xpath.XPath;import com.caucho.xpath.XPathException;import com.caucho.xsl.CauchoStylesheet;import com.caucho.xsl.StylesheetImpl;import com.caucho.xsl.TransformerImpl;import com.caucho.xsl.XslParseException;import org.w3c.dom.Document;import org.w3c.dom.ProcessingInstruction;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.ServletConfig;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspFactory;import javax.servlet.jsp.PageContext;import javax.xml.transform.OutputKeys;import javax.xml.transform.Templates;import javax.xml.transform.TransformerConfigurationException;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import java.io.FileNotFoundException;import java.io.IOException;import java.lang.ref.SoftReference;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.Properties;import java.util.logging.Level;import java.util.logging.Logger;import java.util.concurrent.*;/** * XtpPage represents the compiled page. */class XtpPage extends Page { private static final Logger log = Log.open(XtpPage.class); private boolean _strictXml; private boolean _toLower = true; private boolean _entitiesAsText = false; private Path _sourcePath; private Path _pwd; private String _uri; private String _className; private String _errorPage; private WebApp _webApp; private XslManager _xslManager; private Page _page; private HashMap<String,SoftReference<Page>> _varyMap; private ArrayList<String> _paramNames; private JspManager _jspManager; private final Semaphore _compileSemaphore = new Semaphore(1, false); /** * Creates a new XTP page. * * @param path file containing the xtp page * @param uri the request uri for the page * @param className the mangled classname for the page * @param uriPwd uri working dir for include() or forward() * @param req the servlet request * @param xslManager manager for the XSL stylesheets * @param strictXml if true, use strict XML, now HTML */ XtpPage(Path path, String uri, String className, WebApp app, XslManager xslManager, boolean strictXml) throws ServletException, RegistryException { _sourcePath = path; _sourcePath.setUserPath(uri); _pwd = _sourcePath.getParent(); _className = className; _webApp = app; _strictXml = strictXml; _xslManager = xslManager; _uri = uri; ServletConfigImpl config = new ServletConfigImpl(); config.setServletContext(_webApp); init(config); } /** * Sets the JspManager for the page. */ void setManager(JspManager manager) { _jspManager = manager; } /** * When true, HTML in XTP is normalized to lower-case. */ void setHtmlToLower(boolean toLower) { _toLower = toLower; } /** * When true, XML entities are parsed as text. */ void setEntitiesAsText(boolean entitiesAsText) { _entitiesAsText = entitiesAsText; } /** * Returns true if the sources creating this page have been modified. */ public boolean _caucho_isModified() { return false; } /** * Handle a request. * * @param req the servlet request * @param res the servlet response */ public void service(ServletRequest request, ServletResponse response) throws IOException, ServletException { CauchoRequest req; if (request instanceof CauchoRequest) req = (CauchoRequest) request; else req = RequestAdapter.create((HttpServletRequest) request, _webApp); CauchoResponse res; ResponseAdapter resAdapt = null; if (response instanceof CauchoResponse) res = (CauchoResponse) response; else { resAdapt = ResponseAdapter.create((HttpServletResponse) response); res = resAdapt; } try { service(req, res); } catch (InterruptedException e) { log.log(Level.FINE, e.toString(), e); log.warning("XTP: interrupted for " + req.getPageURI()); res.sendError(503, "Server busy: XTP generation delayed"); } finally { if (resAdapt != null) resAdapt.close(); } } /** * Handle a request. * * @param req the servlet request * @param res the servlet response */ public void service(CauchoRequest req, CauchoResponse res) throws IOException, ServletException, InterruptedException { Page page = getPage(req, res); if (page != null) { page.pageservice(req, res); } else { log.warning("XTP: server busy on " + req.getPageURI()); res.setHeader("Retry-After", "15"); res.sendError(503, "Server busy: XTP generation delayed"); } } /** * Returns the page. */ private Page getPage(CauchoRequest req, CauchoResponse res) throws IOException, ServletException, InterruptedException { String ss = null; String varyName = null; Page page = _page; Page deadPage = null; if (page == null) { if (_varyMap != null) { varyName = generateVaryName(req); if (varyName != null) { SoftReference<Page> ref = _varyMap.get(varyName); page = ref != null ? ref.get() : null; } } } if (page != null && ! page.cauchoIsModified()) return page; deadPage = page; page = null; long timeout = deadPage == null ? 30L : 5L; Thread.interrupted(); if (_compileSemaphore.tryAcquire(timeout, TimeUnit.SECONDS)) { try { varyName = generateVaryName(req); page = getPrecompiledPage(req, varyName); if (page == null) { CauchoDocument doc; try { doc = parseXtp(); } catch (FileNotFoundException e) { res.sendError(404); throw e; } Templates stylesheet = compileStylesheet(req, doc); // the new stylesheet affects the vary name varyName = generateVaryName(req); page = getPrecompiledPage(req, varyName); if (page == null) page = compileJspPage(req, res, doc, stylesheet, varyName); } if (page != null) { ServletConfigImpl config = new ServletConfigImpl(); config.setServletContext(_webApp); page.init(config); if (varyName != null && _varyMap == null) _varyMap = new HashMap<String,SoftReference<Page>>(8); if (varyName != null) _varyMap.put(varyName, new SoftReference<Page>(page)); else _page = page; } else if (deadPage != null) { _page = null; if (varyName != null && _varyMap != null) _varyMap.remove(varyName); } } finally { _compileSemaphore.release(); } } else { log.warning("XTP: semaphore timed out on " + req.getPageURI()); } if (page != null) return page; else return deadPage; } /** * Try to load a precompiled version of the page. * * @param req the request for the page. * @param varyName encoding for the variable stylesheet and parameters * @return the precompiled page or null */ private Page getPrecompiledPage(CauchoRequest req, String varyName) throws IOException, ServletException { Page page = null; String className = getClassName(varyName); try { page = _jspManager.preload(className, _webApp.getClassLoader(), _webApp.getAppDir(), null); if (page != null) { if (log.isLoggable(Level.FINE)) log.fine("XTP using precompiled page " + className); return page; } } catch (Throwable e) { log.log(Level.FINE, e.toString(), e); } return null; } /** * Parses the XTP file as either an XML document or an HTML document. */ private CauchoDocument parseXtp() throws IOException, ServletException { ReadStream is = _sourcePath.openRead(); try { XmlParser parser; if (_strictXml) { parser = new Xml(); parser.setEntitiesAsText(_entitiesAsText); } else { parser = new Html(); parser.setAutodetectXml(true); parser.setEntitiesAsText(true); // parser.setXmlEntitiesAsText(entitiesAsText); parser.setToLower(_toLower); } parser.setResinInclude(true); parser.setJsp(true); return (CauchoDocument) parser.parseDocument(is); } catch (Exception e) { JspParseException jspE = JspParseException.create(e); jspE.setErrorPage(_errorPage); throw jspE; } finally { is.close(); } } /** * Compiles a stylesheet pages on request parameters and the parsed * XML file. * * @param req the servlet request. * @param doc the parsed XTP file as a DOM tree. * * @return the compiled stylesheet */ private Templates compileStylesheet(CauchoRequest req, CauchoDocument doc) throws IOException, ServletException { String ssName = (String) req.getAttribute("caucho.xsl.stylesheet");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?