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