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