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 + -
显示快捷键?