xslnode.java

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

JAVA
1,114
字号
/* * 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.java;import com.caucho.java.JavaWriter;import com.caucho.log.Log;import com.caucho.util.CharBuffer;import com.caucho.util.CompileException;import com.caucho.util.L10N;import com.caucho.util.LineCompileException;import com.caucho.xml.QName;import com.caucho.xml.XmlChar;import com.caucho.xpath.Expr;import com.caucho.xpath.NamespaceContext;import com.caucho.xpath.XPath;import com.caucho.xpath.expr.NumericExpr;import com.caucho.xpath.pattern.*;import com.caucho.xsl.JavaGenerator;import com.caucho.xsl.XslParseException;import java.io.IOException;import java.util.ArrayList;import java.util.logging.Logger;/** * Represents any XSL node from the stylesheet. */public abstract class XslNode {  static final L10N L = new L10N(XslNode.class);  static final Logger log = Log.open(XslNode.class);  protected String _systemId;  protected String _filename;  protected int _startLine;  protected int _endLine;    protected JavaGenerator _gen;  protected QName _name;  protected XslNode _parent;  protected ArrayList<XslNode> _children;  protected NamespaceContext _matchNamespace;  protected NamespaceContext _outputNamespace;  private int _varCount;  protected XslNode()  {  }  /**   * Sets the Java generator.   */  public void setGenerator(JavaGenerator gen)  {    _gen = gen;  }  /**   * Returns the qname of the node.   */  public QName getQName()  {    return _name;  }  /**   * Sets the node's qname   */  public void setQName(QName name)  {    _name = name;  }  /**   * Returns the qname of the node.   */  public String getTagName()  {    if (_name != null)      return _name.getName();    else      return getClass().getName();  }    /**   * Returns the parent node.   */  public XslNode getParent()  {    return _parent;  }  /**   * Sets the parent node   */  public void setParent(XslNode parent)  {    _parent = parent;    if (parent != null) {      _matchNamespace = parent.getMatchNamespace();      _outputNamespace = parent.getOutputNamespace();    }  }  /**   * Add variable.   */  public void addVariableCount()  {    if (_parent != null)      _parent._varCount++;  }  /**   * Sets the start location of the node.   */  public void setStartLocation(String systemId, String filename, int line)  {    _systemId = systemId;    _filename = filename;    _startLine = line;  }  /**   * Sets the end location of the node.   */  public void setEndLocation(String filename, int line)  {    if (_filename != null && _filename.equals(filename))      _endLine = line;  }  /**   * Gets the system id of the node   */  public String getSystemId()  {    return _systemId;  }  /**   * Gets the filename of the node   */  public String getFilename()  {    return _filename;  }  /**   * Gets the starting line number   */  public int getStartLine()  {    return _startLine;  }  /**   * Gets the ending line number   */  public int getEndLine()  {    return _endLine;  }  /**   * Returns the base URI.   */  public String getBaseURI()  {    return _filename;  }  /**   * Returns the namespaces.   */  public NamespaceContext getMatchNamespace()  {    return _matchNamespace;  }  /**   * Returns the namespaces.   */  public NamespaceContext getOutputNamespace()  {    return _outputNamespace;  }  /**   * Returns the matching node in the namespace.   */  public String getNamespace(String prefix)  {    return NamespaceContext.find(getOutputNamespace(), prefix);  }  /**   * Adds an attribute.   */  public void addAttribute(QName name, String value)    throws XslParseException  {    if (name.getName().startsWith("xmlns")) {      addNamespaceAttribute(name, value);      return;    }        if (name.getName().startsWith("xml"))      return;        throw error(L.l("attribute `{0}' is not allowed in <{1}>.",                    name.getName(), getTagName()));  }  /**   * Adds an attribute.   */  protected void addNamespaceAttribute(QName name, String url)    throws XslParseException  {    // Note: according to the spec, the default namespace is not used    /*    if (url.equals(JavaGenerator.XSLNS) || url.equals(JavaGenerator.XTPNS))      return;    if (url.startsWith("quote:"))      url = url.substring(6);    */        String localName = name.getLocalName();    _outputNamespace = new NamespaceContext(_outputNamespace, localName, url);    if (! localName.equals("xmlns")) {      // xsl/04w3      _matchNamespace = new NamespaceContext(_matchNamespace, localName, url);    }  }  /**   * Called after all the attributes from the tag.   */  public void endAttributes()    throws XslParseException  {  }  /**   * Adds text.   */  public void addText(String text)    throws XslParseException  {    for (int i = 0; i < text.length(); i++) {      char ch = text.charAt(i);      if (! XmlChar.isWhitespace(ch))        throw error(L.l("Text is not allowed in <{0}> at `{1}'.",                        _name.getName(), text));    }  }  /**   * Adds a child node.   */  public void addChild(XslNode node)    throws XslParseException  {    if (node == null)      return;        if (_children == null)      _children = new ArrayList<XslNode>();    _children.add(node);  }  /**   * Called when the tag closes.   */  public void endElement()    throws Exception  {  }  /**   * Returns the children.   */  public ArrayList<XslNode> getChildren()  {    return _children;  }  /**   * Returns true if there are any children.   */  public boolean hasChildren()  {    return _children != null && _children.size() > 0;  }  /**   * Generates the code for the tag   *   * @param out the output writer for the generated java.   */  abstract public void generate(JavaWriter out)    throws Exception;  /**   * Generates the code for the children.   *   * @param out the output writer for the generated java.   */  public void generateChildren(JavaWriter out)    throws Exception  {    if (_children == null)      return;    for (int i = 0; i < _children.size(); i++) {      XslNode child = _children.get(i);      out.setLocation(child.getFilename(), child.getStartLine());            child.generate(out);    }    popScope(out);  }  /**   * Generates the prelude code for the tag   *   * @param out the output writer for the generated java.   */  public void generateDeclaration(JavaWriter out)    throws Exception  {    generateDeclarationChildren(out);  }  /**   * Generates the declaration code for the children.   *   * @param out the output writer for the generated java.   */  public void generateDeclarationChildren(JavaWriter out)    throws Exception  {    if (_children == null)      return;    for (int i = 0; i < _children.size(); i++) {      XslNode child = _children.get(i);      child.generateDeclaration(out);    }  }  /**   * Prints an attribute value.   */  protected void printAttributeValue(JavaWriter out, String name, String value)    throws Exception  {    out.print("out.attribute(");    out.print(name == null ? "null" : ("\"" + name + "\""));    out.print(", ");    if (value == null)      out.print("null");    else {      out.print("\"");      out.printJavaString(value);      out.print("\"");    }    out.println(");");  }  /**   * Prints an attribute value.   */  protected void printAttributeValue(JavaWriter out, String value)    throws Exception  {    if (value == null) {      out.print("null");      return;    }    if (value.indexOf("{") < 0) {      out.print("\"");      out.printJavaString(value);      out.print("\"");    }    else {      generateString(out, value);    }  }  /**   * Produces code to generate an attribute value template.  The same   * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of   * print statements (',').   *   * @param string the source template   * @param mode separator: either '+' or ','   * @param elt the containing element.  Needed for namespaces.   */  void generateString(JavaWriter out, String string)    throws Exception  {    int i = 0;    boolean first = true;    int length = string.length();    CharBuffer cb = CharBuffer.allocate();    for (; i < length; i++) {      char ch = string.charAt(i);      if (ch == '\n') {	cb.append("\\n");      }      else if (ch == '"') {	cb.append("\\\"");      }      else if (ch == '{' && i + 1 < length) {	// {{ is treated as a single {	if (string.charAt(i + 1) == '{') {	  cb.append('{');	  i++;	}	// the value is computed from an XPath expr	else {	  // print the gathered text if any	  if (cb.length() > 0) {	    out.print("out.print(\"");	    out.printJavaString(cb.toString());	    out.println("\");");	  }	  // scan the contents of '{' ... '}'	  cb.clear();	  for (i++; i < length && string.charAt(i) != '}'; i++)	    cb.append(string.charAt(i));	  printStringExpr(out, cb.toString());	  cb.clear();	  first = false;	}      }      // }} is treated as a single }      else if (ch == '}' && i + 1 < length) {	if (string.charAt(i + 1) == '}') {	  cb.append('}');	  i++;	}	else	  cb.append('}');      }      // <#= interpolates      else if (i + 2 < length && ch == '<' && 	       string.charAt(i + 1) == '#' &&	       string.charAt(i + 2) == '=') {	// print the gathered text if any	if (cb.length() > 0) {	  out.print("out.print(\"");	  out.printJavaString(cb.toString());	  out.println("\");");	}	// scan the contents of '{' ... '}'	cb.clear();	for (i += 3;	     i + 1 < length && string.charAt(i) != '#' &&	       string.charAt(i + 1) != '>';	     i++)	  cb.append(string.charAt(i));	i++;		// and add the results	out.println("out.print(" + cb + ");");		cb.clear();	first = false;      }      else	cb.append((char) ch);    }    // add any trailing text    if (cb.length() > 0)      out.println("out.print(\"" + cb + "\");");  }  /**   * Produces code to generate an attribute value template.  The same   * code is used to produce a string ('a{b}c' -> "a" + b + "c") or a series of   * print statements (',').   *   * @param string the source template   * @param mode separator: either '+' or ','   * @param elt the containing element.  Needed for namespaces.   */  void generateString(JavaWriter out, String string, int mode)    throws Exception  {    CharBuffer cb = new CharBuffer();    int i = 0;    boolean first = true;    int length = string.length();    for (; i < length; i++) {      char ch = string.charAt(i);      if (ch == '\n') {	cb.append("\\n");      }      else if (ch == '"') {	cb.append("\\\"");      }      else if (ch == '{' && i + 1 < length) {	// {{ is treated as a single {	if (string.charAt(i + 1) == '{') {	  cb.append('{');

⌨️ 快捷键说明

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