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