stylesheetimpl.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 932 行 · 第 1/2 页
JAVA
932 行
/* * 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.xsl;import com.caucho.java.LineMap;import com.caucho.log.Log;import com.caucho.util.CharBuffer;import com.caucho.util.IntArray;import com.caucho.vfs.Path;import com.caucho.xml.CauchoNode;import com.caucho.xml.QAbstractNode;import com.caucho.xml.QElement;import com.caucho.xml.XMLWriter;import com.caucho.xml.XmlChar;import com.caucho.xml.XmlUtil;import com.caucho.xpath.Env;import com.caucho.xpath.Expr;import com.caucho.xpath.StylesheetEnv;import com.caucho.xpath.XPath;import com.caucho.xpath.XPathException;import com.caucho.xpath.XPathFun;import com.caucho.xpath.pattern.AbstractPattern;import com.caucho.xpath.pattern.NodeIterator;import com.caucho.xsl.fun.DocumentFun;import com.caucho.xsl.fun.ExtensionElementFun;import com.caucho.xsl.fun.ExtensionFunctionFun;import com.caucho.xsl.fun.SystemPropertyFun;import com.caucho.xsl.fun.UnparsedEntityFun;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.Text;import org.xml.sax.SAXException;import javax.xml.transform.TransformerException;import java.io.IOException;import java.util.ArrayList;import java.util.Comparator;import java.util.HashMap;import java.util.Iterator;import java.util.Locale;import java.util.logging.Logger;/** * Implementation base class for stylesheets. It is made public only * because generated Java and JavaScript classes need to access these * routines. */public class StylesheetImpl extends AbstractStylesheet { static final Logger log = Log.open(StylesheetImpl.class); public char []text; // static buffer of the text nodes protected HashMap templates; HashMap<String,XPathFun> _funs = new HashMap<String,XPathFun>(); private HashMap<String,String> _preserve; private HashMap<String,String> _strip; private HashMap<String,String> _preservePrefix; private HashMap<String,String> _stripPrefix; private HashMap<String,Object> _properties = new HashMap<String,Object>(); boolean isCacheable = true; protected boolean _defaultDisableEscaping; Path cachePath; long lastModified; boolean _generateLocation; LineMap lineMap; protected void copy(AbstractStylesheet stylesheet) { super.copy(stylesheet); StylesheetImpl stylesheetImpl = (StylesheetImpl) stylesheet; stylesheetImpl.text = text; stylesheetImpl.templates = templates; stylesheetImpl._preserve = _preserve; stylesheetImpl._strip = _strip; stylesheetImpl._preservePrefix = _preservePrefix; stylesheetImpl._stripPrefix = _stripPrefix; stylesheetImpl.lineMap = lineMap; stylesheetImpl._properties = _properties; stylesheetImpl._defaultDisableEscaping = _defaultDisableEscaping; } public OutputFormat getOutputFormat() { return new OutputFormat(); } public void setOutputFormat(OutputFormat output) { } protected void setSpaces(HashMap<String,String> preserve, HashMap<String,String> preservePrefix, HashMap<String,String> strip, HashMap<String,String> stripPrefix) { _preserve = preserve; _strip = strip; _preservePrefix = preservePrefix; _stripPrefix = stripPrefix; } public void setProperty(String name, Object value) { _properties.put(name, value); } public void setGenerateLocation(boolean generateLocation) { _generateLocation = generateLocation; } public boolean getGenerateLocation() { return _generateLocation; } public Object getProperty(String name) { Object value = _properties.get(name); if (value != null) return value; return super.getProperty(name); } protected void addFunction(String name, XPathFun fun) { _funs.put(name, fun); } public void init(Path path) throws Exception { super.init(path); addFunction("system-property", new SystemPropertyFun()); addFunction("element-available", new ExtensionElementFun()); addFunction("function-available", new ExtensionFunctionFun()); addFunction("unparsed-entity-uri", new UnparsedEntityFun()); } /** * Transforms the input node to the output writer * * @param xml the input node to be transformed * @param writer output writer receiving the output * @param transformer the transformer to be used */ public void transform(Node xml, XMLWriter writer, TransformerImpl transformer) throws SAXException, IOException, TransformerException { if (xml == null) throw new NullPointerException("can't transform null node"); XslWriter out = new XslWriter(null, this, transformer); out.init(writer); if (_funs == null) _funs = (HashMap) ((StylesheetImpl) _stylesheet)._funs.clone(); else _funs.putAll((HashMap) ((StylesheetImpl) _stylesheet)._funs); addFunction("document", new DocumentFun(transformer)); DocumentFun docFun = new DocumentFun(transformer); docFun.setHtml(true); addFunction("html_document", docFun); Env env = XPath.createEnv(); env.setFunctions(_funs); StylesheetEnv ssEnv = new StylesheetEnv(); ssEnv.setPath(getPath()); env.setStylesheetEnv(ssEnv); out.disableEscaping(_defaultDisableEscaping); if (_strip != null && ! _strip.isEmpty()) { stripSpaces(xml); } try { _xsl_init(out, xml, env); applyNode(out, xml, env, 0, Integer.MAX_VALUE); } catch (TransformerException e) { throw e; } catch (IOException e) { throw e; } catch (SAXException e) { throw e; } catch (Exception e) { throw new XslException(e, lineMap); } out.close(); XPath.freeEnv(env); // funs = null; } protected void _xsl_init(XslWriter out, Node context, Env env) throws Exception { } protected Document ownerDocument(Node node) { Document owner = node.getOwnerDocument(); if (owner != null) return owner; else return (Document) node; } public void applyNode(XslWriter out, Node node, Env env) throws Exception { applyNode(out, node, env, Integer.MIN_VALUE, Integer.MAX_VALUE); } protected void applyNode(XslWriter out, Node node, Env env, int min, int max) throws Exception { if (node == null) return; switch (node.getNodeType()) { case Node.DOCUMENT_NODE: case Node.DOCUMENT_FRAGMENT_NODE: for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { applyNode(out, child, env, 0, 2147483647); } break; case Node.ELEMENT_NODE: out.pushCopy(node); if (node instanceof QElement) { for (Node child = ((QElement) node).getFirstAttribute(); child != null; child = child.getNextSibling()) { applyNode(out, child, env, 0, 2147483647); } } else { NamedNodeMap attributeMap = ((Element) node).getAttributes(); int size = attributeMap.getLength(); for (int i = 0; i < size; i++) { Node child = attributeMap.item(i); applyNode(out, child, env, 0, 2147483647); } } for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { applyNode(out, child, env, 0, 2147483647); } out.popCopy(node); break; case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: String value = node.getNodeValue(); out.print(value); return; case Node.ATTRIBUTE_NODE: out.pushCopy(node); out.popCopy(node); break; case Node.ENTITY_REFERENCE_NODE: out.pushCopy(node); out.popCopy(node); break; } } /** * Gets a template. * * Only those templates with importance between min and max are considered. * For apply-templates, min = 0, and max = Infinity, * * @param min minimum allowed importance * @param max maximum allowed importance */ protected Template getTemplate(HashMap templates, Node node, Env env, int min, int max) throws XPathException { Template template = null; Template []templateList = (Template []) templates.get(node.getNodeName()); if (templateList == null) templateList = (Template []) templates.get("*"); for (int i = 0; templateList != null && i < templateList.length; i++) { Template subtemplate = templateList[i]; if (min <= subtemplate.maxImportance && subtemplate.maxImportance <= max && subtemplate.pattern.match(node, env)) { return subtemplate; } } return null; } /** * The default rule when no templates match. By default, it * calls apply-template on element children and copies text. All * other nodes are stripped. * * @param out the current writer. * @param node the current node. * @param env the xpath environment. */ protected void applyNodeDefault(XslWriter out, Node node, Env env) throws Exception { switch (node.getNodeType()) { case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: if (_generateLocation && node instanceof QAbstractNode) out.setLocation(((QAbstractNode) node).getBaseURI(), ((QAbstractNode) node).getFilename(), ((QAbstractNode) node).getLine()); String value = node.getNodeValue(); out.print(value); return; case Node.ATTRIBUTE_NODE: case Node.ENTITY_REFERENCE_NODE: out.print(node.getNodeValue()); break; case Node.ELEMENT_NODE: case Node.DOCUMENT_NODE: throw new RuntimeException(); } } public void printValue(XslWriter out, Node node) throws IOException { if (node != null) out.print(getNodeValue(node)); } public String getNodeValue(Node node) { CharBuffer cb = new CharBuffer(); nodeValue(cb, node); return cb.toString(); } private void nodeValue(CharBuffer cb, Node node) { if (node == null) return; switch (node.getNodeType()) { case Node.ELEMENT_NODE: for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) { switch (child.getNodeType()) { case Node.ELEMENT_NODE: case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: case Node.ENTITY_REFERENCE_NODE: nodeValue(cb, child); break; } } break; case Node.ENTITY_REFERENCE_NODE: cb.append('&'); cb.append(node.getNodeName()); cb.append(';'); break; case Node.DOCUMENT_NODE: Document doc = (Document) node; nodeValue(cb, doc.getDocumentElement()); break; case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: String value = node.getNodeValue(); cb.append(value); break; default: cb.append(node.getNodeValue()); break; } } protected ArrayList xslSort(Node node, Env env, AbstractPattern pattern, Sort []sortList) throws Exception { ArrayList<Node> sortKeys = new ArrayList<Node>(); Iterator<Node> sortIter; NodeIterator iter = pattern.select(node, env); while (iter.hasNext()) { Node child = iter.next(); sortKeys.add(child); } int []map = new int[sortKeys.size()]; for (int i = map.length - 1; i >= 0; i--) map[i] = i; int []workMap = new int[map.length]; Object []values = new Object[map.length * sortList.length];
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?