xpathparser.java

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

JAVA
1,355
字号
  {    int ch = skipWhitespace(read());    ArrayList<Expr> args = new ArrayList<Expr>();    for (; ch >= 0 && ch != ')'; ch = skipWhitespace(read())) {      if (ch != ',')	unread();      Expr expr = parseExpr(parent, listParent);      if (expr == null)        throw error(L.l("null expression"));            args.add(expr);    }    int code = exprFunctions.get(name);    switch (code) {    case Expr.TRUE: case Expr.FALSE: case Expr.NOT: case Expr.BOOLEAN:    case Expr.STARTS_WITH: case Expr.CONTAINS: case Expr.LANG:    case Expr.FUNCTION_AVAILABLE:      return new BooleanExpr(code, args);    case Expr.NUMBER: case Expr.FLOOR: case Expr.CEILING: case Expr.ROUND:    case Expr.STRING_LENGTH:      return new NumericExpr(code, args);    case Expr.POSITION:     case Expr.LAST:      return new NumericExpr(code, listParent);    case Expr.COUNT: case Expr.SUM:      if (args.size() == 0)	args.add(NodeSetExpr.create(new FromContext()));      return new NumericExpr(code, ((Expr) args.get(0)).toNodeList());    case Expr.CONCAT:     case Expr.SUBSTRING_BEFORE:    case Expr.SUBSTRING: case Expr.SUBSTRING_AFTER:    case Expr.TRANSLATE:     case Expr.SYSTEM_PROPERTY:      return new StringExpr(code, args);    case Expr.STRING: case Expr.NORMALIZE:      return new StringExpr(code, args);    case Expr.LOCAL_PART: case Expr.NAMESPACE:    case Expr.QNAME: case Expr.GENERATE_ID:      if (args.size() == 0)	args.add(NodeSetExpr.create(new FromContext()));      return new StringExpr(code, args);    case Expr.ID:      if (args.size() == 0) {	args.add(NodeSetExpr.create(parent));	return new IdExpr(args);      }      else	return new IdExpr(args);    case Expr.IF:      if (args.size() != 3)        throw error(L.l("`if' needs three args."));      return new ObjectExpr(code, args);    case Expr.BASE_URI:      if (args.size() != 1)        throw error(L.l("`base-uri' needs one args."));      return new StringExpr(code, args.get(0));    case TEXT:      if (fromChildren)	parent = new FromChildren(parent);      AbstractPattern pattern = NodeTypePattern.create(parent, Node.TEXT_NODE);      return NodeSetExpr.create(pattern);    case COMMENT:      if (fromChildren)	parent = new FromChildren(parent);      pattern = NodeTypePattern.create(parent, Node.COMMENT_NODE);      return NodeSetExpr.create(pattern);    case ER:      if (fromChildren)	parent = new FromChildren(parent);      pattern = NodeTypePattern.create(parent, Node.ENTITY_REFERENCE_NODE);      return NodeSetExpr.create(pattern);    case PI:      if (fromChildren)	parent = new FromChildren(parent);      if (args.size() == 1) {	Expr expr = (Expr) args.get(0);	String value = null;	if (expr instanceof StringExpr)	  value = ((StringExpr) expr).getValue();	if (value == null)	  throw error(L.l("processing-instruction expects string literal"));	pattern = new NodePattern(parent, value,				  Node.PROCESSING_INSTRUCTION_NODE);      }      else	pattern = NodeTypePattern.create(parent, Node.PROCESSING_INSTRUCTION_NODE);      return NodeSetExpr.create(pattern);    case NODE:      if (fromChildren)	parent = new FromChildren(parent);      pattern = NodeTypePattern.create(parent, NodeTypePattern.NODE);      return NodeSetExpr.create(pattern);    case CURRENT:      return NodeSetExpr.create(new CurrentPattern());    case CONTEXT:      return NodeSetExpr.create(new FromContext());    default:      Expr function = constructorFunction(name, args);      if (function != null)	return function;            int p = name.lastIndexOf(':');      String prefix;            if (p > 0)        prefix = name.substring(0, p);      else	prefix = "";            String context = NamespaceContext.find(_namespace, prefix);      if (context == null) {      }      else if (context.startsWith("java:"))	name = context + "." + name.substring(p + 1);      else if (context.indexOf(':') < 0)	name = "java:" + context + "." + name.substring(p + 1);            if (name.startsWith("java:")) {        p = name.lastIndexOf('.');        if (p < 0)          throw error(L.l("`{0}' is an illegal extension function.  Java extension functions must look like java:mypkg.MyClass.mymethod.", name));        String className = name.substring(5, p);        String methodName = name.substring(p + 1);        Class cl;        try {          cl = CauchoSystem.loadClass(className);        } catch (ClassNotFoundException e) {          throw error(L.l("`{0}' is an unknown Java class.  Java extension functions must use public classes.", className));        }        if (methodName.equals("new")) {          Constructor []constructors = cl.getConstructors();                    for (int i = 0; i < constructors.length; i++) {            if (constructors[i].getParameterTypes().length == args.size())              return new NewJavaExpr(constructors[i], args);          }                      throw error(L.l("No matching public constructor in `{0}'",                          className));        }        Method method = null;        Method []methods = cl.getMethods();        if (args.size() > 0) {          for (int i = 0; i < methods.length; i++) {            if (methods[i].getName().equals(methodName) &&                methods[i].getParameterTypes().length == args.size() - 1 &&                ! Modifier.isStatic(methods[i].getModifiers())) {              Expr objArg = (Expr) args.remove(0);              return new ObjectJavaExpr(methods[i], objArg, args);            }          }        }        for (int i = 0; i < methods.length; i++) {          if (methods[i].getName().equals(methodName) &&              methods[i].getParameterTypes().length == args.size()) {            method = methods[i];            break;          }        }        if (method == null)          throw error(L.l("`{0}' does not match a public method in `{1}'",                          methodName, className));        if (! Modifier.isStatic(method.getModifiers()))          throw error(L.l("`{0}' is not a static method in `{1}'",                          methodName, className));        return new StaticJavaExpr(method, args);      }      else if (name.equals(""))	throw error(L.l("expected node-test at `{0}'", "("));      return new FunExpr(name, parent, args);    }  }  private Expr constructorFunction(String name, ArrayList<Expr> args)    throws XPathParseException  {    Constructor constructor = _exprFunctions.get(name);    if (constructor == null)      return null;        Class []params = constructor.getParameterTypes();    if (params.length < args.size())      throw error(L.l("`{0}' needs {1} arguments",		      name, "" + params.length));    Object []values = new Object[params.length];        for (int i = 0; i < args.size(); i++)      values[i] = args.get(i);    try {      return (Expr) constructor.newInstance(values);    } catch (Throwable e) {      throw new XPathParseException(e);    }  }  private Expr parseNodeSetExpr(AbstractPattern parent, String name, int nodeType)    throws XPathParseException  {    AbstractPattern top = parseAxis(parent, name, true, nodeType);    top = parseFilter(top);    return NodeSetExpr.create(parseUnion(parsePath(top), parent));  }  /**   * Scans the next token.   *   * @return token code, expressed as an Expr enumeration.   */  private int scanToken()    throws XPathParseException  {    if (peek >= 0) {      int value = peek;      peek = -1;      return value;    }    int ch = skipWhitespace(read());    switch (ch) {    case '+': return Expr.ADD;    case '-': return Expr.SUB;    case '*': return Expr.MUL;    case '=': return Expr.EQ;    case '!':      ch = read();      if (ch == '=')	return Expr.NEQ;      else	throw error(L.l("expected `{0}' at {1}", "=", badChar(ch)));    case '<':      ch = read();      if (ch == '=')	return Expr.LE;      else {	unread();	return Expr.LT;      }    case '>':      ch = read();      if (ch == '=')	return Expr.GE;      else {	unread();	return Expr.GT;      }    default:      if (XmlChar.isNameStart(ch)) {	String name = readName(ch);	if (name.equals("div"))	  return Expr.DIV;	else if (name.equals("quo"))	  return Expr.QUO;	else if (name.equals("mod"))	  return Expr.MOD;	else if (name.equals("and"))	  return Expr.AND;	else if (name.equals("or"))	  return Expr.OR;	else	  throw error(L.l("expected binary operation at `{0}'", name));      }      unread();      return -1;    }  }  private String readName(int ch)  {    tag.clear();    for (; XmlChar.isNameChar(ch); ch = read())      tag.append((char) ch);        if (ch == '*' && tag.endsWith(":"))      tag.append((char) ch);    else      unread();    return tag.toString();  }  private void undoToken(int token)  {    peek = token;  }  private int read()  {    if (index < _string.length()) {      return _string.charAt(index++);    }    else {      index++;      return -1;    }  }  private void unread()  {    index--;  }    private XPathParseException error(String message)  {    return new XPathParseException(message + " in " + _string);  }    private String badChar(int ch)  {    if (ch < 0)      return L.l("end of file");    else if (ch == '\n')      return L.l("end of line");    else      return "`" + (char) ch + "'";  }  private int skipWhitespace(int ch)    throws XPathParseException  {    for (; ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; ch = read()) {    }    return ch;  }  private static void addFunction(String name, Class cl)  {    Constructor []constructors = cl.getConstructors();        _exprFunctions.put(name, constructors[0]);  }  static {    exprFunctions = new IntMap();    exprFunctions.put("id", Expr.ID);    exprFunctions.put("true", Expr.TRUE);    exprFunctions.put("false", Expr.FALSE);    exprFunctions.put("not", Expr.NOT);    exprFunctions.put("boolean", Expr.BOOLEAN);    exprFunctions.put("starts-with", Expr.STARTS_WITH);    exprFunctions.put("contains", Expr.CONTAINS);    exprFunctions.put("lang", Expr.LANG);    exprFunctions.put("number", Expr.NUMBER);    exprFunctions.put("sum", Expr.SUM);    exprFunctions.put("floor", Expr.FLOOR);    exprFunctions.put("ceiling", Expr.CEILING);    exprFunctions.put("round", Expr.ROUND);    exprFunctions.put("position", Expr.POSITION);    exprFunctions.put("count", Expr.COUNT);    exprFunctions.put("last", Expr.LAST);    exprFunctions.put("string-length", Expr.STRING_LENGTH);    exprFunctions.put("string", Expr.STRING);    exprFunctions.put("concat", Expr.CONCAT);    exprFunctions.put("substring", Expr.SUBSTRING);    exprFunctions.put("substring-before", Expr.SUBSTRING_BEFORE);    exprFunctions.put("substring-after", Expr.SUBSTRING_AFTER);    exprFunctions.put("normalize-space", Expr.NORMALIZE);    exprFunctions.put("translate", Expr.TRANSLATE);    exprFunctions.put("local-name", Expr.LOCAL_PART);    exprFunctions.put("local-part", Expr.LOCAL_PART);    exprFunctions.put("namespace-uri", Expr.NAMESPACE);    exprFunctions.put("name", Expr.QNAME);    exprFunctions.put("generate-id", Expr.GENERATE_ID);    exprFunctions.put("if", Expr.IF);        exprFunctions.put("text", TEXT);    exprFunctions.put("comment", COMMENT);    exprFunctions.put("er", ER);    exprFunctions.put("entity-reference", ER);    exprFunctions.put("pi", PI);    exprFunctions.put("processing-instruction", PI);    exprFunctions.put("node", NODE);    exprFunctions.put("current", CURRENT);    exprFunctions.put("context", CONTEXT);    axisMap = new IntMap();    axisMap.put("ancestor", ANCESTOR_AXIS);    axisMap.put("ancestor-or-self", ANCESTOR_OR_SELF_AXIS);    axisMap.put("attribute", ATTRIBUTE_AXIS);    axisMap.put("child", CHILD_AXIS);    axisMap.put("descendant", DESCENDANT_AXIS);    axisMap.put("descendant-or-self", DESCENDANT_OR_SELF_AXIS);    axisMap.put("following", FOLLOWING_AXIS);    axisMap.put("following-sibling", FOLLOWING_SIBLING_AXIS);    axisMap.put("namespace", NAMESPACE_AXIS);    axisMap.put("parent", PARENT_AXIS);    axisMap.put("preceding", PRECEDING_AXIS);    axisMap.put("preceding-sibling", PRECEDING_SIBLING_AXIS);    axisMap.put("self", SELF_AXIS);    _exprFunctions = new HashMap<String,Constructor>();    addFunction("fn:base-uri", BaseURI.class);    addFunction("fn:resolve-uri", ResolveURI.class);    addFunction("fn:trace", Trace.class);  }}

⌨️ 快捷键说明

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