stringexpr.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 443 行

JAVA
443
字号
/* * 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.xpath.expr;import com.caucho.util.CharBuffer;import com.caucho.xml.XmlChar;import com.caucho.xpath.Expr;import com.caucho.xpath.ExprEnvironment;import com.caucho.xpath.XPathException;import org.w3c.dom.Node;import java.util.ArrayList;import java.util.Iterator;/** * Implements the builtin XPath string expressions. */public class StringExpr extends Expr {  // Code of the expression defined in Expr  private int _code;  // First argument  private Expr _left;  // Second argument  private Expr _right;  // Third  private Expr _third;  private String _value;  // Arguments for more than 3.  private ArrayList _args;  /**   * Create a StringExpression with three arguments.   *   * @param code the Expr code of the expression.   * @param left the first argument.   * @param right the second argument.   * @param third the third argument.   */  public StringExpr(int code, Expr left, Expr right, Expr third)  {    _code = code;    _left = left;    _right = right;    _third = third;  }  public StringExpr(int code, Expr left, Expr right)  {    _code = code;    _left = left;    _right = right;  }  public StringExpr(int code, Expr expr)  {    _code = code;    _left = expr;  }  public StringExpr(String value)  {    _code = CONST;    _value = value;  }  /**   * Creates a string expression from a list of arguments.   *   * @param code Expr code for the function.   * @param args array list of the arguments.   */  public StringExpr(int code, ArrayList args)  {    _code = code;    _args = args;    if (args.size() > 0)      _left = (Expr) args.get(0);    if (args.size() > 1)      _right = (Expr) args.get(1);    if (args.size() > 2)      _third = (Expr) args.get(2);  }  /**   * The StringExpr returns a string value.   */  public boolean isString()  {    return true;  }  public String getValue()  {    return _value;  }  /**   * Evaluates the expression as an string.   *   * @param node the current node   * @param env the variable environment.   *   * @return the string representation of the expression.   */  public String evalString(Node node, ExprEnvironment env)    throws XPathException  {    switch (_code) {    case CONST:      return _value;    case STRING:      return _left.evalString(node, env);    case CONCAT:       CharBuffer cb = CharBuffer.allocate();      for (int i = 0; i < _args.size(); i++)	((Expr) _args.get(i)).evalString(cb, node, env);      return cb.close();    case SUBSTRING_BEFORE:      String lstr = _left.evalString(node, env);      String rstr = _right.evalString(node, env);      int index = lstr.indexOf(rstr);      return index > 0 ? lstr.substring(0, index) : "";    case SUBSTRING_AFTER:      lstr = _left.evalString(node, env);      rstr = _right.evalString(node, env);      index = lstr.indexOf(rstr);      return index >= 0 ? lstr.substring(index + rstr.length()) : "";    case NORMALIZE:      lstr = _left.evalString(node, env);      return normalize(lstr);    case TRANSLATE:      lstr = _left.evalString(node, env);      rstr = _right.evalString(node, env);      String tstr = _third.evalString(node, env);      return translate(lstr, rstr, tstr);    case FORMAT_NUMBER:      return _left.evalString(node, env);    case LOCAL_PART:      Object lobj = _left.evalObject(node, env);      Node nodeValue = toNode(lobj);      if (nodeValue != null)	return nodeValue.getLocalName();      else	return "";    case NAMESPACE:      lobj = _left.evalObject(node, env);      nodeValue = toNode(lobj);      if (nodeValue != null) {	String uri = nodeValue.getNamespaceURI();	return uri != null ? uri : "";      }      else	return "";    case QNAME:      lobj = _left.evalObject(node, env);      nodeValue = toNode(lobj);      if (nodeValue != null)	return nodeValue.getNodeName();      else	return "";    case GENERATE_ID:      Iterator iter = _left.evalNodeSet(node, env);      return "G" + String.valueOf(System.identityHashCode(iter.next()));    case SYSTEM_PROPERTY:      lstr = _left.evalString(node, env);      if (lstr == null)	return "";      else if (lstr.equals("xsl:version"))	return "1.0";      else	return "";    case SUBSTRING:      lstr = _left.evalString(node, env);      if (lstr == null)	lstr = "";      double start = _right.evalNumber(node, env) - 1;            double end = lstr.length();      if (_third != null)	end = Math.round(start) + _third.evalNumber(node, env);      if (Double.isNaN(end) || Double.isNaN(start)) {        start = 0;        end = 0;      }      if (start < 0)        start = 0;      else if (lstr.length() < start)        start = lstr.length();            if (end < 0)        end = 0;      else if (end < start)        end = start;      else if (lstr.length() < end)        end = lstr.length();      return lstr.substring((int) (start + 0.5), (int) (end + 0.5));    default:      throw new RuntimeException("unknown code: " + _code);    }  }  /**   * Evaluate the expression as a boolean, i.e. evaluate it as a string   * and then convert it to a boolean.   *   * @param node the current node   * @param env the variable environment.   *   * @return the boolean representation of the expression.   */  public boolean evalBoolean(Node node, ExprEnvironment env)    throws XPathException  {    String string = evalString(node, env);    return string != null && string.length() > 0;  }  /**   * Evaluate the expression as a double, i.e. evaluate it as a string   * and then convert it to a double.   *   * @param node the current node   * @param env the variable environment.   *   * @return the numeric representation of the expression.   */  public double evalNumber(Node node, ExprEnvironment env)    throws XPathException  {    return stringToNumber(evalString(node, env));  }  /**   * Evaluate the expression as an object, i.e. return the string value.   *   * @param node the current node   * @param env the variable environment.   *   * @return the boolean representation of the expression.   */  public Object evalObject(Node node, ExprEnvironment env)    throws XPathException  {    return evalString(node, env);  }  /**   * Normalize the string, converting all whitespace to a space and   * eliminating consecutive spaces.   */  private String normalize(String string)  {    CharBuffer result = new CharBuffer();    int i = 0;    int len = string.length();    for (; i < len && XmlChar.isWhitespace(string.charAt(i)); i++) {    }    boolean lastIsWhitespace = false;    for (; i < len; i++) {      if (XmlChar.isWhitespace(string.charAt(i))) {	lastIsWhitespace = true;      }      else if (lastIsWhitespace) {	result.append(' ');	result.append(string.charAt(i));	lastIsWhitespace = false;      }      else	result.append(string.charAt(i));    }    return result.toString();  }  /**   * Translate the string, converting characters.  translate("foo", "f", "b")   * returns "boo".   *   * @param string the string to translate.   * @param from characters to convert from.   * @param to the replacement characters.   */  private String translate(String string, String from, String to)  {    CharBuffer result = new CharBuffer();  loop:    for (int i = 0; i < string.length(); i++) {      char ch = string.charAt(i);      for (int j = 0; j < from.length(); j++) {	if (ch == from.charAt(j)) {	  if (to.length() > j)	    result.append(to.charAt(j));	  continue loop;	}      }      result.append(ch);    }    return result.toString();  }  /**   * Return the expression as a string.  toString() returns a valid   * XPath expression.  This lets applications like XSLT use toString()   * to print the string in the generated Java.   */  public String toString()  {    switch (_code) {    case CONST:      CharBuffer cb = CharBuffer.allocate();      cb.append("'");      for (int i = 0; i < _value.length(); i++) {        char ch = _value.charAt(i);        switch (ch) {        case '\n':          cb.append("\\n");          break;        case '\r':          cb.append("\\r");          break;        case '\\':          cb.append("\\\\");          break;        case '\'':          cb.append("\\'\\'");          break;        case '"':          cb.append("\\\"");          break;        default:          cb.append(ch);        }      }      cb.append("'");      return cb.toString();          case STRING: return "string(" + _left + ")";    case CONCAT:       String result = "concat(";      for (int i = 0; i < _args.size(); i++) {	if (i > 0)	  result = result + ", ";	result = result + _args.get(i);      }      return result + ")";    case SUBSTRING_BEFORE:      return "substring-before(" + _left + ", " + _right + ")";     case SUBSTRING_AFTER:      return "substring-after(" + _left + ", " + _right + ")";     case NORMALIZE:      return "normalize-space(" + _left + ")";    case TRANSLATE:      return "translate(" + _left + ", " + _right + ", " + _third + ")";    case FORMAT_NUMBER:      return "format-number(" + _left + ")";    case LOCAL_PART:      return "local-part(" + _left + ")";    case NAMESPACE:      return "namespace-uri(" + _left + ")";    case QNAME:      return "name(" + _left + ")";    case GENERATE_ID:      return "generate-id(" + _left + ")";    case SYSTEM_PROPERTY:      return "system-property(" + _left + ")";    case SUBSTRING:      return "substring(" + _left + "," + _right + 	(_third == null ? "" : ("," + _third)) + ")";    case BASE_URI:      return "fn:base-uri(" + _left + ")";    default:      return super.toString();    }  }}

⌨️ 快捷键说明

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