generator.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 2,537 行 · 第 1/5 页

JAVA
2,537
字号
/* * 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 SoftwareFoundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.xsl;import com.caucho.java.JavaWriter;import com.caucho.java.LineMap;import com.caucho.log.Log;import com.caucho.util.CharBuffer;import com.caucho.util.CharScanner;import com.caucho.util.IntArray;import com.caucho.util.IntMap;import com.caucho.util.L10N;import com.caucho.util.StringCharCursor;import com.caucho.vfs.Path;import com.caucho.vfs.ReadStream;import com.caucho.xml.CauchoDocument;import com.caucho.xml.QAbstractNode;import com.caucho.xml.QElement;import com.caucho.xml.QName;import com.caucho.xml.Xml;import com.caucho.xml.XmlChar;import com.caucho.xpath.Expr;import com.caucho.xpath.NamespaceContext;import com.caucho.xpath.XPath;import com.caucho.xpath.pattern.AbstractPattern;import com.caucho.xpath.pattern.UnionPattern;import com.caucho.xsl.fun.FormatNumberFun;import com.caucho.xsl.fun.KeyFun;import com.caucho.xsl.java.XslAttributeSet;import com.caucho.xsl.java.XslNode;import com.caucho.xsl.java.XslStylesheet;import com.caucho.xsl.java.XslTemplate;import org.w3c.dom.Attr;import org.w3c.dom.Document;import org.w3c.dom.DocumentType;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.Text;import java.io.FileNotFoundException;import java.io.IOException;import java.text.DecimalFormatSymbols;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.logging.Level;import java.util.logging.Logger;/** * Base class for generating code from an XSL tree.  JavaGenerator and * JavaScriptGenerator extend this class for language-specific code * generation. */abstract class Generator {  private static final Logger log = Log.open(Generator.class);  protected static final L10N L = new L10N(Generator.class);  public static final String XSLNS = "http://www.w3.org/1999/XSL/Transform";  public static final String XTPNS = "http://www.caucho.com/XTP/1.0";  private static final int STYLESHEET = 0;  private static final int OUTPUT = STYLESHEET + 1;  private static final int IMPORT = OUTPUT + 1;  private static final int INCLUDE = IMPORT + 1;  private static final int TEMPLATE = INCLUDE + 1;  private static final int STRIP_SPACE = TEMPLATE + 1;  private static final int PRESERVE_SPACE = STRIP_SPACE + 1;  private static final int KEY = PRESERVE_SPACE + 1;  private static final int LOCALE = KEY + 1;  private static final int ATTRIBUTE_SET = LOCALE + 1;  private static final int NAMESPACE_ALIAS = ATTRIBUTE_SET + 1;  private static final int APPLY_TEMPLATES = NAMESPACE_ALIAS + 1;  private static final int APPLY_IMPORTS = APPLY_TEMPLATES + 1;  private static final int CALL_TEMPLATE = APPLY_IMPORTS + 1;  private static final int PARAM = CALL_TEMPLATE + 1;  private static final int VARIABLE = PARAM + 1;  private static final int VALUE_OF = VARIABLE + 1;  private static final int COPY_OF = VALUE_OF + 1;  private static final int FOR_EACH = COPY_OF + 1;  private static final int IF = FOR_EACH + 1;  private static final int CHOOSE = IF + 1;  private static final int TEXT = CHOOSE + 1;  private static final int XSL_TEXT = TEXT + 1;  private static final int NUMBER = XSL_TEXT + 1;  private static final int COPY = NUMBER + 1;  private static final int COPY_ELEMENT = COPY + 1;  private static final int ELEMENT = COPY_ELEMENT + 1;  private static final int ATTRIBUTE = ELEMENT + 1;  private static final int PI = ATTRIBUTE + 1;  private static final int COMMENT = PI + 1;  private static final int MESSAGE = COMMENT + 1;  private static final int EXPRESSION = MESSAGE + 1;  private static final int SCRIPTLET = EXPRESSION + 1;  private static final int DECLARATION = SCRIPTLET + 1;  private static final int DIRECTIVE_CACHE = DECLARATION + 1;  private static final int DIRECTIVE_PAGE = DIRECTIVE_CACHE + 1;  private static final int WHILE = DIRECTIVE_PAGE + 1;  private static final int ASSIGN = WHILE + 1;  private static final int IGNORE = ASSIGN + 1;  // xslt 2.0  private static final int RESULT_DOCUMENT = IGNORE + 1;  private static IntMap _tags;  private static IntMap _xtpTags;  private String _version = "1.0";  String _xslName;  // the root context  Path _topContext;  // the pwd for the file  Path _baseURL;  Path _context;  CharBuffer _text;  HashMap<String,String> _names = new HashMap<String,String>();  int _loopDepth;  Path _workPath;  int _uniqueId;  protected HashMap<String,String> _preserve = new HashMap<String,String>();  protected HashMap<String,String> _strip = new HashMap<String,String>();  HashMap<String,XslAttributeSet> _attributeSets =    new HashMap<String,XslAttributeSet>();  protected HashMap<String,String[]> _namespaceAliases =    new HashMap<String,String[]>();  protected HashMap<String,String> _excludedNamespaces =    new HashMap<String,String>();  protected KeyFun _keyFun;  protected FormatNumberFun _formatNumberFun;  protected NamespaceContext _namespace;  protected ArrayList _globalActions = new ArrayList();  protected ArrayList<String> _globalParameters =    new ArrayList<String>();  protected Document _doc;  protected CauchoDocument _qDoc;  protected Path _path;  boolean _lineContent;  int _lineWs;  String _systemId;  String _filename;  int _line;  protected LineMap _lineMap;  private ArrayList _frags;  protected int _destLine = 1;  boolean _defaultCacheable = true;  boolean _isCacheable;  protected String _encoding;  HashMap<String,ArrayList<Template>> _templates = new HashMap<String,ArrayList<Template>>();  int _minImportance; // for included files, the minimum importance  int _importance;  int _templateCount;  private IntArray _vars = new IntArray();  private ArrayList<XslNode> _inits = new ArrayList<XslNode>();  protected ArrayList<Path> _depends = new ArrayList<Path>();  protected ArrayList<String> _cacheDepends = new ArrayList<String>();  private boolean _isCauchoXsl;  protected boolean _isRawText;  protected String _errorPage;  boolean _hasSession;  protected AbstractPattern _nodeListContext;  private boolean _isTop;  private ClassLoader _loader;  protected boolean _isSpecial;  protected boolean _isStyleScript;  HashMap<String,String> _outputAttributes = new HashMap<String,String>();  HashMap<String,String> _macros;  HashMap<String,Document> _files;    protected AbstractStylesheetFactory _xslGenerator;  protected ArrayList<String> _imports = new ArrayList<String>();  Generator(AbstractStylesheetFactory xslGenerator)  {    _xslGenerator = xslGenerator;        _workPath = xslGenerator.getWorkPath();    Path path = xslGenerator.getStylePath();    _context = path;    _topContext = _context;    _loader = xslGenerator.getClassLoader();    if (_loader == null)      _loader = Thread.currentThread().getContextClassLoader();        _text = new CharBuffer();    _frags = new ArrayList();    _macros = new HashMap<String,String>();    _keyFun = new KeyFun();    _formatNumberFun = new FormatNumberFun();  }  void init(String filename)  {    _lineMap = new LineMap(filename);  }    public void setErrorPage(String errorPage)  {    _errorPage = errorPage;  }  public void setStyleScript(boolean stylescript)  {    _isStyleScript = stylescript;  }  /**   * Adds a Java import to the generated stylesheet.   */  public void addImport(String pkg)  {    if (! _imports.contains(pkg))      _imports.add(pkg);  }    public void setContentType(String type)  {    // contentType = type;  }  void setPath(Path path)  {    _path = path;    _context = path;  }  void setWorkPath(Path path)  {    _workPath = path;  }  public int getMinImportance()  {    return _minImportance;  }  public int getMaxImportance()  {    return _importance;  }  public NamespaceContext getNamespace()  {    return _namespace;  }  public AbstractPattern getNodeListContext()  {    return _nodeListContext;  }  public void addLocale(String name, DecimalFormatSymbols format)  {    _formatNumberFun.addLocale(name, format);  }  /**   * Generates a uniqueId   */  public int uniqueId()  {    return _uniqueId++;  }  /**   * Starts the generation from the top of the document.   *   * @param xsl the stylesheet document.   */  public StylesheetImpl generate(Node node) throws Exception  {    Document xsl = node.getOwnerDocument();    if (xsl == null)      xsl = (Document) node;    DocumentType dtd = xsl.getDoctype();    if (dtd != null && dtd.getSystemId() != null) {      _context = _path.lookup(dtd.getSystemId());      _topContext = _context;    }        Element top = (Element) xsl.getDocumentElement();    if (top == null)      throw error(xsl, L.l("xsl:stylesheet must be top element."));    _doc = xsl;    if (_doc instanceof CauchoDocument)      _qDoc = (CauchoDocument) _doc;    QElement qTop = null;    if (top instanceof QElement)      qTop = (QElement) top;    /*    if (qTop != null && qTop.getFilename() != null)      context = topContext.lookup(qTop.getFilename()).getParent();    */        _isTop = true;    _files = new HashMap<String,Document>();    scanFiles(top);    if (_qDoc != null) {      ArrayList depends = (ArrayList) _qDoc.getProperty(CauchoDocument.DEPENDS);      for (int i = 0; depends != null && i < depends.size(); i++) {        Path path = (Path) depends.get(i);        addDepend(path);      }    }    else {      addDepend(_path);    }    if ("stylesheet".equals(getXslLocal(top)) ||	"transform".equals(getXslLocal(top))) {      generateStylesheet(top, true);    }    else {      // literal result element      printHeader();      boolean oldCacheable = _isCacheable;      boolean oldDefaultCacheable = _defaultCacheable;      _isCacheable = true;          XslNode literal = createChild(top);      XslTemplate template = new XslTemplate();      template.setGenerator((JavaGenerator) this);      template.addAttribute(new QName("match"), "/");      template.addChild(literal);      template.generateDeclaration(getOut());          template.generate(getOut());      // printTemplate(top, null, "/", null, 0.0/0.0);            _isCacheable = oldCacheable;      _defaultCacheable = oldDefaultCacheable;    }    addNamespace(top);    StylesheetImpl stylesheet = completeGenerate(_inits, _globalActions);    return stylesheet;  }  private static CharScanner commaDelimScanner = new CharScanner(" \t\n\r,");  /**   * Scan the stylesheet for imported packages and files.  The imported   * stylesheets will be read and stored in the 'files' HashMap for when   * they're actually needed.   */  private void scanFiles(Element top)    throws XslParseException, IOException  {    _isCauchoXsl = ! top.getAttribute("xsl-caucho").equals("");    Iterator iter;    try {      iter = XPath.select("//xtp:directive.page/@*", top);    } catch (Exception e) {      throw new XslParseException(e);    }    while (iter.hasNext()) {      Attr attr = (Attr) iter.next();      String name = attr.getNodeName();      String value = attr.getNodeValue();      if (name.equals("import")) {        StringCharCursor cursor = new StringCharCursor(value);        CharBuffer cb = new CharBuffer();        while (cursor.current() != cursor.DONE) {          char ch;          commaDelimScanner.skip(cursor);          cb.clear();          ch = commaDelimScanner.scan(cursor, cb);          if (cb.length() != 0) {            addImport(cb.toString());          }          else if (ch != cursor.DONE)            throw new IOException(L.l("illegal `import' directive"));        }      }    }    try {      iter = XPath.select("//xsl:import|xsl:include", top);    } catch (Exception e) {      throw new XslParseException(e);    }    while (iter.hasNext()) {      Element elt = (Element) iter.next();      String href = elt.getAttribute("href");      ReadStream rs;      try {        rs = _xslGenerator.openPath(href, _context.getURL());      } catch (Exception e) {        throw new XslParseException(e);      }      Path path = rs.getPath();            Document xsl = readXsl(rs);      Element subtop = xsl.getDocumentElement();      if (subtop == null)        throw error(elt, L.l("xsl:import file {0} is empty", path.getFullPath()));            Path oldContext = _context;      Path virtualPath = _context.getParent().lookup(href);      _context = virtualPath;      _files.put(virtualPath.getPath(), xsl);            scanFiles(subtop);      _context = oldContext;    }  }  public void addImportList(String value)    throws XslParseException  {    StringCharCursor cursor = new StringCharCursor(value);    CharBuffer cb = new CharBuffer();    while (cursor.current() != cursor.DONE) {      char ch;      commaDelimScanner.skip(cursor);      cb.clear();      ch = commaDelimScanner.scan(cursor, cb);      if (cb.length() != 0) {	addImport(cb.toString());      }      else if (ch != cursor.DONE)	throw error(L.l("illegal `import' directive"));    }  }  /**   * Read in an imported or included XSL file.   *   * @param path Path to the include files.   *   * @return XML tree describing the XSL.   */  Document readXsl(Path path)    throws IOException, XslParseException  {    return readXsl(path.openRead());  }  /**   * Read in an imported or included XSL file.

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?