Source Code Cross Referenced for XPathParser.java in  » EJB-Server-resin-3.1.5 » resin » com » caucho » xpath » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » EJB Server resin 3.1.5 » resin » com.caucho.xpath 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
0003:         *
0004:         * This file is part of Resin(R) Open Source
0005:         *
0006:         * Each copy or derived work must preserve the copyright notice and this
0007:         * notice unmodified.
0008:         *
0009:         * Resin Open Source is free software; you can redistribute it and/or modify
0010:         * it under the terms of the GNU General Public License as published by
0011:         * the Free Software Foundation; either version 2 of the License, or
0012:         * (at your option) any later version.
0013:         *
0014:         * Resin Open Source is distributed in the hope that it will be useful,
0015:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0016:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
0017:         * of NON-INFRINGEMENT.  See the GNU General Public License for more
0018:         * details.
0019:         *
0020:         * You should have received a copy of the GNU General Public License
0021:         * along with Resin Open Source; if not, write to the
0022:         *   Free SoftwareFoundation, Inc.
0023:         *   59 Temple Place, Suite 330
0024:         *   Boston, MA 02111-1307  USA
0025:         *
0026:         * @author Scott Ferguson
0027:         */
0028:
0029:        package com.caucho.xpath;
0030:
0031:        import com.caucho.log.Log;
0032:        import com.caucho.server.util.CauchoSystem;
0033:        import com.caucho.util.CharBuffer;
0034:        import com.caucho.util.IntMap;
0035:        import com.caucho.util.L10N;
0036:        import com.caucho.xml.XmlChar;
0037:        import com.caucho.xpath.expr.*;
0038:        import com.caucho.xpath.functions.BaseURI;
0039:        import com.caucho.xpath.functions.ResolveURI;
0040:        import com.caucho.xpath.functions.Trace;
0041:        import com.caucho.xpath.pattern.*;
0042:
0043:        import org.w3c.dom.Node;
0044:
0045:        import java.lang.reflect.Constructor;
0046:        import java.lang.reflect.Method;
0047:        import java.lang.reflect.Modifier;
0048:        import java.util.ArrayList;
0049:        import java.util.HashMap;
0050:        import java.util.logging.Logger;
0051:
0052:        /**
0053:         * Parses an XPath expression.
0054:         */
0055:        class XPathParser {
0056:            private static final Logger log = Log.open(XPathParser.class);
0057:            private static final L10N L = new L10N(XPathParser.class);
0058:
0059:            private final static int ANCESTOR_AXIS = 0;
0060:            private final static int ANCESTOR_OR_SELF_AXIS = ANCESTOR_AXIS + 1;
0061:            private final static int ATTRIBUTE_AXIS = ANCESTOR_OR_SELF_AXIS + 1;
0062:            private final static int CHILD_AXIS = ATTRIBUTE_AXIS + 1;
0063:            private final static int DESCENDANT_AXIS = CHILD_AXIS + 1;
0064:            private final static int DESCENDANT_OR_SELF_AXIS = DESCENDANT_AXIS + 1;
0065:            private final static int FOLLOWING_AXIS = DESCENDANT_OR_SELF_AXIS + 1;
0066:            private final static int FOLLOWING_SIBLING_AXIS = FOLLOWING_AXIS + 1;
0067:            private final static int NAMESPACE_AXIS = FOLLOWING_SIBLING_AXIS + 1;
0068:            private final static int PARENT_AXIS = NAMESPACE_AXIS + 1;
0069:            private final static int PRECEDING_AXIS = PARENT_AXIS + 1;
0070:            private final static int PRECEDING_SIBLING_AXIS = PRECEDING_AXIS + 1;
0071:            private final static int SELF_AXIS = PRECEDING_SIBLING_AXIS + 1;
0072:
0073:            private final static int TEXT = Expr.LAST_FUN + 1;
0074:            private final static int COMMENT = TEXT + 1;
0075:            private final static int ER = COMMENT + 1;
0076:            private final static int PI = ER + 1;
0077:            private final static int NODE = PI + 1;
0078:            private final static int CURRENT = NODE + 1;
0079:            private final static int NODE_TEXT = CURRENT + 1;
0080:            private final static int CONTEXT = NODE_TEXT + 1;
0081:
0082:            private static IntMap exprFunctions;
0083:            private static IntMap axisMap;
0084:
0085:            private static HashMap<String, Constructor> _exprFunctions;
0086:
0087:            private CharBuffer tag = new CharBuffer();
0088:
0089:            private String _string;
0090:            private int index;
0091:            private int peek;
0092:
0093:            private NamespaceContext _namespace;
0094:
0095:            XPathParser(String string, NamespaceContext namespace) {
0096:                _string = string;
0097:                _namespace = namespace;
0098:            }
0099:
0100:            /**
0101:             * Parse a select pattern, i.e. a path rooted in a context.
0102:             */
0103:            AbstractPattern parseSelect() throws XPathParseException {
0104:                AbstractPattern top = new FromContext();
0105:
0106:                AbstractPattern pattern = parseUnion(parseTop(top), top);
0107:
0108:                if (index < _string.length())
0109:                    throw error(L.l("unexpected character at `{0}'",
0110:                            badChar(read())));
0111:
0112:                return pattern;
0113:            }
0114:
0115:            /**
0116:             * Parse a match pattern, i.e. a path with no root.
0117:             */
0118:            AbstractPattern parseMatch() throws XPathParseException {
0119:                AbstractPattern root = new FromAny();
0120:                AbstractPattern pattern = parseUnion(parseTop(root), root);
0121:
0122:                if (index < _string.length())
0123:                    throw error(L.l("unexpected character at `{0}'",
0124:                            badChar(read())));
0125:
0126:                return pattern;
0127:            }
0128:
0129:            /**
0130:             * Parse an expression.
0131:             */
0132:            Expr parseExpr() throws XPathParseException {
0133:                Expr expr = parseExpr(null, null);
0134:
0135:                if (index < _string.length())
0136:                    throw error(L.l("unexpected character at `{0}'",
0137:                            badChar(read())));
0138:
0139:                return expr;
0140:            }
0141:
0142:            private AbstractPattern parseStep(AbstractPattern root)
0143:                    throws XPathParseException {
0144:                return parseUnion(parseTop(root), root);
0145:            }
0146:
0147:            private AbstractPattern parseUnion(AbstractPattern left,
0148:                    AbstractPattern root) throws XPathParseException {
0149:                int ch = skipWhitespace(read());
0150:
0151:                while (ch >= 0) {
0152:                    if (ch == '|') {
0153:                        AbstractPattern tail = parseUnion(parseTop(root), root);
0154:                        left = new UnionPattern(left, tail);
0155:                    } else
0156:                        break;
0157:
0158:                    for (ch = read(); XmlChar.isWhitespace(ch); ch = read()) {
0159:                    }
0160:                }
0161:
0162:                unread();
0163:
0164:                return left;
0165:            }
0166:
0167:            /**
0168:             * Parses the top expression.
0169:             *
0170:             * <pre>
0171:             *  top ::= (expr)
0172:             *      ::= term
0173:             * </pre>
0174:             */
0175:            private AbstractPattern parseTop(AbstractPattern pattern)
0176:                    throws XPathParseException {
0177:                int ch = skipWhitespace(read());
0178:                unread();
0179:
0180:                if (ch == '(') {
0181:                    Expr expr = parseTerm(pattern, pattern);
0182:
0183:                    // If the expression is really a pattern and the iterator is
0184:                    // ascending, then just unwrap it.
0185:                    if (expr instanceof  NodeSetExpr) {
0186:                        AbstractPattern nodeSet = ((NodeSetExpr) expr)
0187:                                .getPattern();
0188:
0189:                        if (nodeSet.isAscending())
0190:                            return nodeSet;
0191:                    }
0192:
0193:                    return new FromExpr(null, expr);
0194:                } else
0195:                    return parseTerm(pattern, pattern).toNodeList();
0196:            }
0197:
0198:            private AbstractPattern parseBasisTop(AbstractPattern pattern)
0199:                    throws XPathParseException {
0200:                int ch;
0201:
0202:                ch = skipWhitespace(read());
0203:                if (ch == '/') {
0204:                    ch = read();
0205:                    if (ch == '/') {
0206:                        pattern = new FromRoot();
0207:                        pattern = new FromDescendants(pattern, false);
0208:                        pattern = parseBasis(pattern);
0209:                        pattern = parseFilter(pattern);
0210:                        pattern = parsePath(pattern);
0211:
0212:                        return pattern;
0213:                    }
0214:                    pattern = new FromRoot();
0215:                    ch = skipWhitespace(ch);
0216:
0217:                    if (ch == -1)
0218:                        return pattern;
0219:                }
0220:
0221:                unread();
0222:
0223:                if (pattern == null)
0224:                    pattern = new FromContext();
0225:
0226:                pattern = parseBasis(pattern);
0227:                pattern = parseFilter(pattern);
0228:
0229:                return parsePath(pattern);
0230:            }
0231:
0232:            /**
0233:             * path ::= top ('/' filter)*
0234:             */
0235:            private AbstractPattern parsePath(AbstractPattern pattern)
0236:                    throws XPathParseException {
0237:                int ch = skipWhitespace(read());
0238:
0239:                while (ch == '/') {
0240:                    ch = read();
0241:
0242:                    if (ch == '/') {
0243:                        pattern = new FromDescendants(pattern, false);
0244:                        pattern = parseBasis(pattern);
0245:                        pattern = parseFilter(pattern);
0246:                    } else {
0247:                        unread();
0248:                        pattern = parseBasis(pattern);
0249:                        pattern = parseFilter(pattern);
0250:                    }
0251:
0252:                    ch = skipWhitespace(read());
0253:                }
0254:
0255:                unread();
0256:
0257:                return pattern;
0258:            }
0259:
0260:            /**
0261:             * filter ::= atom('[' expr ']')*
0262:             */
0263:            private AbstractPattern parseFilter(AbstractPattern pattern)
0264:                    throws XPathParseException {
0265:                int ch = skipWhitespace(read());
0266:                while (ch == '[') {
0267:                    AbstractPattern context = new FromContext();
0268:                    Expr expr = parseExpr(context, pattern);
0269:                    pattern = new FilterPattern(pattern, expr);
0270:
0271:                    ch = skipWhitespace(read());
0272:                    if (ch != ']')
0273:                        throw error(L.l("expected `{0}' at {1}", "]",
0274:                                badChar(ch)));
0275:
0276:                    ch = skipWhitespace(read());
0277:                }
0278:                unread();
0279:
0280:                return pattern;
0281:            }
0282:
0283:            /**
0284:             * basis ::= name::node-test
0285:             *         | node-test
0286:             *         | @node-test
0287:             *         | .
0288:             *         | ..
0289:             *         ;
0290:             */
0291:            private AbstractPattern parseBasis(AbstractPattern pattern)
0292:                    throws XPathParseException {
0293:                boolean fromChildren = true;
0294:                int ch = skipWhitespace(read());
0295:
0296:                int nodeType = Node.ELEMENT_NODE;
0297:                String namespace = null;
0298:                tag.clear();
0299:
0300:                if (ch == '@') {
0301:                    if (pattern instanceof  FromDescendants)
0302:                        pattern = NodeTypePattern.create(pattern,
0303:                                NodeTypePattern.NODE);
0304:
0305:                    pattern = new FromAttributes(pattern);
0306:                    nodeType = Node.ATTRIBUTE_NODE;
0307:                    fromChildren = false;
0308:                    ch = read();
0309:                } else if (ch == '.') {
0310:                    ch = read();
0311:                    if (ch == '.')
0312:                        return NodeTypePattern.create(new FromParent(pattern),
0313:                                NodeTypePattern.NODE);
0314:                    else {
0315:                        unread();
0316:                        if (pattern != null)
0317:                            return pattern;
0318:                        else
0319:                            return NodeTypePattern.create(
0320:                                    new FromSelf(pattern), NodeTypePattern.ANY);
0321:                    }
0322:                } else if (ch == '(') {
0323:                    // XXX: not strictly correct for counting
0324:                    Expr expr = parseExpr(null, null);
0325:
0326:                    if ((ch = read()) != ')')
0327:                        throw error(L.l("expected `{0}' at {1}", ")",
0328:                                badChar(ch)));
0329:
0330:                    return new FromExpr(pattern, expr);
0331:                }
0332:
0333:                if (ch == '*') {
0334:                    tag.append('*');
0335:                }
0336:
0337:                else if (XmlChar.isNameStart(ch)) {
0338:                    for (; XmlChar.isNameChar(ch); ch = read())
0339:                        tag.append((char) ch);
0340:
0341:                    if (ch == '*' && tag.endsWith(":"))
0342:                        tag.append('*');
0343:                    else
0344:                        unread();
0345:                } else
0346:                    unread();
0347:
0348:                String name = tag.toString();
0349:
0350:                if (name.equals(""))
0351:                    throw error(L.l("expected name at {0}", badChar(ch)));
0352:
0353:                return parseAxis(pattern, name, fromChildren, nodeType);
0354:            }
0355:
0356:            private AbstractPattern parseAxis(AbstractPattern pattern,
0357:                    String name, boolean fromChildren, int nodeType)
0358:                    throws XPathParseException {
0359:                String axis = "";
0360:                int axisIndex = name.indexOf("::");
0361:
0362:                if (axisIndex >= 0 && nodeType != Node.ATTRIBUTE_NODE) {
0363:                    axis = name.substring(0, axisIndex);
0364:                    name = name.substring(axisIndex + 2);
0365:                }
0366:
0367:                if (pattern instanceof  FromDescendants)
0368:                    return parseNodeTest(pattern, name, false,
0369:                            Node.ELEMENT_NODE);
0370:
0371:                switch (axisMap.get(axis)) {
0372:                case ANCESTOR_AXIS:
0373:                    return parseNodeTest(new FromAncestors(pattern, false),
0374:                            name, false, Node.ELEMENT_NODE);
0375:
0376:                case ANCESTOR_OR_SELF_AXIS:
0377:                    return parseNodeTest(new FromAncestors(pattern, true),
0378:                            name, false, Node.ELEMENT_NODE);
0379:
0380:                case ATTRIBUTE_AXIS:
0381:                    return parseNodeTest(new FromAttributes(pattern), name,
0382:                            false, Node.ATTRIBUTE_NODE);
0383:
0384:                case CHILD_AXIS:
0385:                    return parseNodeTest(new FromChildren(pattern), name,
0386:                            false, Node.ELEMENT_NODE);
0387:
0388:                case DESCENDANT_AXIS:
0389:                    return parseNodeTest(new FromDescendants(pattern, false),
0390:                            name, false, Node.ELEMENT_NODE);
0391:
0392:                case DESCENDANT_OR_SELF_AXIS:
0393:                    return parseNodeTest(new FromDescendants(pattern, true),
0394:                            name, false, Node.ELEMENT_NODE);
0395:
0396:                case FOLLOWING_AXIS:
0397:                    return parseNodeTest(new FromNext(pattern), name, false,
0398:                            Node.ELEMENT_NODE);
0399:
0400:                case FOLLOWING_SIBLING_AXIS:
0401:                    return parseNodeTest(new FromNextSibling(pattern), name,
0402:                            false, Node.ELEMENT_NODE);
0403:
0404:                case NAMESPACE_AXIS:
0405:                    return parseNodeTest(new FromNamespace(pattern), name,
0406:                            false, Node.ATTRIBUTE_NODE);
0407:
0408:                case PARENT_AXIS:
0409:                    return parseNodeTest(new FromParent(pattern), name, false,
0410:                            Node.ELEMENT_NODE);
0411:
0412:                case PRECEDING_AXIS:
0413:                    return parseNodeTest(new FromPrevious(pattern), name,
0414:                            false, Node.ELEMENT_NODE);
0415:
0416:                case PRECEDING_SIBLING_AXIS:
0417:                    return parseNodeTest(new FromPreviousSibling(pattern),
0418:                            name, false, Node.ELEMENT_NODE);
0419:
0420:                case SELF_AXIS:
0421:                    return parseNodeTest(new FromSelf(pattern), name, false,
0422:                            Node.ELEMENT_NODE);
0423:
0424:                default:
0425:                    return parseNodeTest(pattern, name, fromChildren, nodeType);
0426:                }
0427:            }
0428:
0429:            /**
0430:             * node-test ::= qname
0431:             *             | *:name
0432:             *             | *
0433:             *             | name '(' args ')'
0434:             *             ;
0435:             */
0436:            private AbstractPattern parseNodeTest(AbstractPattern pattern,
0437:                    String name, boolean fromChildren, int nodeType)
0438:                    throws XPathParseException {
0439:                int ch = skipWhitespace(read());
0440:
0441:                AbstractPattern tagPattern;
0442:
0443:                if (ch == '(') {
0444:                    Expr expr = parseFunction(pattern, pattern, name,
0445:                            fromChildren);
0446:                    return expr.toNodeList();
0447:                } else if (ch == '{') {
0448:                    tag.clear();
0449:                    while ((ch = read()) >= 0 && ch != '}')
0450:                        tag.append((char) ch);
0451:                    String url = tag.toString();
0452:                    tag.clear();
0453:                    for (ch = read(); XmlChar.isNameChar(ch); ch = read())
0454:                        tag.append((char) ch);
0455:
0456:                    pattern = new NSNamePattern(pattern, url, tag.toString(),
0457:                            nodeType);
0458:                } else {
0459:                    if (fromChildren)
0460:                        pattern = new FromChildren(pattern);
0461:
0462:                    if (name.equals("*"))
0463:                        pattern = NodeTypePattern.create(pattern, nodeType);
0464:                    else if (name.endsWith(":*")) {
0465:                        pattern = new NamespacePattern(pattern, name.substring(
0466:                                0, name.length() - 2), nodeType);
0467:                    } else {
0468:                        int p = name.indexOf(':');
0469:                        String ns = null;
0470:                        String local = name;
0471:
0472:                        if (p > 0) {
0473:                            String prefix = name.substring(0, p);
0474:                            ns = NamespaceContext.find(_namespace, prefix);
0475:                            local = name.substring(p + 1);
0476:                        } else if (nodeType != Node.ATTRIBUTE_NODE)
0477:                            ns = _namespace.find(_namespace, "");
0478:                        else
0479:                            ns = null; // _namespace.find(_namespace, "");
0480:
0481:                        if (ns == null)
0482:                            pattern = new NodePattern(pattern, name, nodeType);
0483:                        else
0484:                            pattern = new NSNamePattern(pattern, ns, local,
0485:                                    nodeType);
0486:                    }
0487:                }
0488:                unread();
0489:
0490:                return pattern;
0491:            }
0492:
0493:            /**
0494:             * expr ::= or-expr
0495:             */
0496:            Expr parseExpr(AbstractPattern parent, AbstractPattern listParent)
0497:                    throws XPathParseException {
0498:                peek = -1;
0499:                Expr left = parseTerm(parent, listParent);
0500:
0501:                while (true) {
0502:                    int token = scanToken();
0503:                    switch (token) {
0504:                    case Expr.OR:
0505:                        left = parseOrExpr(token, left, parseTerm(parent,
0506:                                listParent), parent, listParent);
0507:                        break;
0508:
0509:                    case Expr.AND:
0510:                        left = parseAndExpr(token, left, parseTerm(parent,
0511:                                listParent), parent, listParent);
0512:                        break;
0513:
0514:                    case Expr.EQ:
0515:                    case Expr.NEQ:
0516:                    case Expr.LT:
0517:                    case Expr.LE:
0518:                    case Expr.GT:
0519:                    case Expr.GE:
0520:                        left = parseCmpExpr(token, left, parseTerm(parent,
0521:                                listParent), parent, listParent);
0522:                        break;
0523:
0524:                    case Expr.ADD:
0525:                    case Expr.SUB:
0526:                        left = parseAddExpr(token, left, parseTerm(parent,
0527:                                listParent), parent, listParent);
0528:                        break;
0529:
0530:                    case Expr.MUL:
0531:                    case Expr.DIV:
0532:                    case Expr.QUO:
0533:                    case Expr.MOD:
0534:                        left = parseMulExpr(token, left, parseTerm(parent,
0535:                                listParent), parent, listParent);
0536:                        break;
0537:
0538:                    default:
0539:                        return left;
0540:                    }
0541:                }
0542:            }
0543:
0544:            /**
0545:             * or-expr ::= or-expr 'OR' expr
0546:             *           | and-expr
0547:             */
0548:            private Expr parseOrExpr(int code, Expr left, Expr right,
0549:                    AbstractPattern parent, AbstractPattern listParent)
0550:                    throws XPathParseException {
0551:                while (true) {
0552:                    int token = scanToken();
0553:                    switch (token) {
0554:                    case Expr.OR:
0555:                        left = new BooleanExpr(code, left, right);
0556:                        code = token;
0557:                        right = parseTerm(parent, listParent);
0558:                        break;
0559:
0560:                    case Expr.AND:
0561:                        right = parseAndExpr(token, right, parseTerm(parent,
0562:                                listParent), parent, listParent);
0563:                        break;
0564:
0565:                    case Expr.EQ:
0566:                    case Expr.NEQ:
0567:                    case Expr.LT:
0568:                    case Expr.LE:
0569:                    case Expr.GT:
0570:                    case Expr.GE:
0571:                        right = parseCmpExpr(token, right, parseTerm(parent,
0572:                                listParent), parent, listParent);
0573:                        break;
0574:
0575:                    case Expr.ADD:
0576:                    case Expr.SUB:
0577:                        right = parseAddExpr(token, right, parseTerm(parent,
0578:                                listParent), parent, listParent);
0579:                        break;
0580:
0581:                    case Expr.MUL:
0582:                    case Expr.DIV:
0583:                    case Expr.QUO:
0584:                    case Expr.MOD:
0585:                        right = parseMulExpr(token, right, parseTerm(parent,
0586:                                listParent), parent, listParent);
0587:                        break;
0588:
0589:                    default:
0590:                        undoToken(token);
0591:                        return new BooleanExpr(code, left, right);
0592:                    }
0593:                }
0594:            }
0595:
0596:            /**
0597:             * and-expr ::= and-expr 'AND' expr
0598:             *            | cmp-expr
0599:             */
0600:            private Expr parseAndExpr(int code, Expr left, Expr right,
0601:                    AbstractPattern parent, AbstractPattern listParent)
0602:                    throws XPathParseException {
0603:                while (true) {
0604:                    int token = scanToken();
0605:                    switch (token) {
0606:                    case Expr.AND:
0607:                        left = new BooleanExpr(code, left, right);
0608:                        code = token;
0609:                        right = parseTerm(parent, listParent);
0610:                        break;
0611:
0612:                    case Expr.EQ:
0613:                    case Expr.NEQ:
0614:                    case Expr.LT:
0615:                    case Expr.LE:
0616:                    case Expr.GT:
0617:                    case Expr.GE:
0618:                        right = parseCmpExpr(token, right, parseTerm(parent,
0619:                                listParent), parent, listParent);
0620:                        break;
0621:
0622:                    case Expr.ADD:
0623:                    case Expr.SUB:
0624:                        right = parseAddExpr(token, right, parseTerm(parent,
0625:                                listParent), parent, listParent);
0626:                        break;
0627:
0628:                    case Expr.MUL:
0629:                    case Expr.DIV:
0630:                    case Expr.QUO:
0631:                    case Expr.MOD:
0632:                        right = parseMulExpr(token, right, parseTerm(parent,
0633:                                listParent), parent, listParent);
0634:                        break;
0635:
0636:                    default:
0637:                        undoToken(token);
0638:                        return new BooleanExpr(code, left, right);
0639:                    }
0640:                }
0641:            }
0642:
0643:            /**
0644:             * cmp-expr ::= cmp-expr '<' expr
0645:             *            | add-expr
0646:             */
0647:            private Expr parseCmpExpr(int code, Expr left, Expr right,
0648:                    AbstractPattern parent, AbstractPattern listParent)
0649:                    throws XPathParseException {
0650:                while (true) {
0651:                    int token = scanToken();
0652:                    switch (token) {
0653:                    case Expr.EQ:
0654:                    case Expr.NEQ:
0655:                    case Expr.LT:
0656:                    case Expr.LE:
0657:                    case Expr.GT:
0658:                    case Expr.GE:
0659:                        left = new BooleanExpr(code, left, right);
0660:                        code = token;
0661:                        right = parseTerm(parent, listParent);
0662:                        break;
0663:
0664:                    case Expr.ADD:
0665:                    case Expr.SUB:
0666:                        right = parseAddExpr(token, right, parseTerm(parent,
0667:                                listParent), parent, listParent);
0668:                        break;
0669:
0670:                    case Expr.MUL:
0671:                    case Expr.DIV:
0672:                    case Expr.QUO:
0673:                    case Expr.MOD:
0674:                        right = parseMulExpr(token, right, parseTerm(parent,
0675:                                listParent), parent, listParent);
0676:                        break;
0677:
0678:                    default:
0679:                        undoToken(token);
0680:                        return new BooleanExpr(code, left, right);
0681:                    }
0682:                }
0683:            }
0684:
0685:            /**
0686:             * add-expr ::= add-expr '+' expr
0687:             *            | mul-expr
0688:             */
0689:            private Expr parseAddExpr(int code, Expr left, Expr right,
0690:                    AbstractPattern parent, AbstractPattern listParent)
0691:                    throws XPathParseException {
0692:                while (true) {
0693:                    int token = scanToken();
0694:                    switch (token) {
0695:                    case Expr.ADD:
0696:                    case Expr.SUB:
0697:                        left = new NumericExpr(code, left, right);
0698:                        code = token;
0699:                        right = parseTerm(parent, listParent);
0700:                        break;
0701:
0702:                    case Expr.MUL:
0703:                    case Expr.DIV:
0704:                    case Expr.QUO:
0705:                    case Expr.MOD:
0706:                        right = parseMulExpr(token, right, parseTerm(parent,
0707:                                listParent), parent, listParent);
0708:                        break;
0709:
0710:                    default:
0711:                        undoToken(token);
0712:                        return new NumericExpr(code, left, right);
0713:                    }
0714:                }
0715:            }
0716:
0717:            /**
0718:             * mul-expr ::= mul-expr '*' expr
0719:             *            | term
0720:             */
0721:            private Expr parseMulExpr(int code, Expr left, Expr right,
0722:                    AbstractPattern parent, AbstractPattern listParent)
0723:                    throws XPathParseException {
0724:                while (true) {
0725:                    int token = scanToken();
0726:                    switch (token) {
0727:                    case Expr.MUL:
0728:                    case Expr.DIV:
0729:                    case Expr.QUO:
0730:                    case Expr.MOD:
0731:                        left = new NumericExpr(code, left, right);
0732:                        code = token;
0733:                        right = parseTerm(parent, listParent);
0734:                        break;
0735:
0736:                    default:
0737:                        undoToken(token);
0738:                        return new NumericExpr(code, left, right);
0739:                    }
0740:                }
0741:            }
0742:
0743:            /**
0744:             * term ::= simple-term path?
0745:             */
0746:            private Expr parseTerm(AbstractPattern parent,
0747:                    AbstractPattern listParent) throws XPathParseException {
0748:                int ch = skipWhitespace(read());
0749:                unread();
0750:                Expr expr = parseSimpleTerm(parent, listParent);
0751:
0752:                int nextCh = skipWhitespace(read());
0753:                unread();
0754:                if (nextCh == '/' || nextCh == '[') {
0755:                    AbstractPattern pattern = expr.toNodeList();
0756:
0757:                    if (ch == '(' && !pattern.isStrictlyAscending())
0758:                        pattern = new FromExpr(null, expr);
0759:
0760:                    return NodeSetExpr.create(parseUnion(
0761:                            parsePath(parseFilter(pattern)), pattern));
0762:                } else if (nextCh == '|') {
0763:                    AbstractPattern pattern = expr.toNodeList();
0764:
0765:                    return NodeSetExpr.create(parseUnion(
0766:                            parsePath(parseFilter(pattern)), listParent));
0767:                } else
0768:                    return expr;
0769:            }
0770:
0771:            /**
0772:             * simple-term ::= number
0773:             *             ::= '(' expr ')'
0774:             *             ::= '$' variable
0775:             *             ::= '"' string '"'
0776:             *             ::= node-set
0777:             */
0778:            private Expr parseSimpleTerm(AbstractPattern parent,
0779:                    AbstractPattern listParent) throws XPathParseException {
0780:                int ch = read();
0781:
0782:                ch = skipWhitespace(ch);
0783:
0784:                switch (ch) {
0785:                case '.':
0786:                    ch = read();
0787:                    unread();
0788:                    unread();
0789:                    if (!('0' <= ch && ch <= '9')) {
0790:                        return NodeSetExpr.create(parseUnion(
0791:                                parseBasisTop(parent), parent));
0792:                    }
0793:                    ch = read();
0794:                    // fall through to parse the number
0795:
0796:                case '0':
0797:                case '1':
0798:                case '2':
0799:                case '3':
0800:                case '4':
0801:                case '5':
0802:                case '6':
0803:                case '7':
0804:                case '8':
0805:                case '9': {
0806:                    long value = 0;
0807:                    double exp = 1;
0808:                    int digits = 0;
0809:                    for (; ch >= '0' && ch <= '9'; ch = read())
0810:                        value = 10 * value + ch - '0';
0811:                    if (ch == '.') {
0812:                        for (ch = read(); ch >= '0' && ch <= '9'; ch = read()) {
0813:                            value = 10 * value + ch - '0';
0814:                            exp *= 10;
0815:                            digits--;
0816:                        }
0817:                    }
0818:
0819:                    if (ch == 'e' || ch == 'E') {
0820:                        int sign = 1;
0821:                        int expValue = 0;
0822:
0823:                        ch = read();
0824:                        if (ch == '-') {
0825:                            sign = -1;
0826:                            ch = read();
0827:                        } else if (ch == '+')
0828:                            ch = read();
0829:
0830:                        for (; ch >= '0' && ch <= '9'; ch = read())
0831:                            expValue = 10 * expValue + ch - '0';
0832:
0833:                        exp = Math.pow(10, digits + sign * expValue);
0834:
0835:                        unread();
0836:
0837:                        return new NumericExpr((double) value * (double) exp);
0838:                    }
0839:
0840:                    unread();
0841:                    return new NumericExpr((double) value / (double) exp);
0842:                }
0843:
0844:                case '-':
0845:                    return new NumericExpr(Expr.NEG, parseTerm(parent,
0846:                            listParent));
0847:
0848:                case '+':
0849:                    return parseTerm(parent, listParent);
0850:
0851:                case '(': {
0852:                    Expr expr = parseExpr(parent, listParent);
0853:                    if ((ch = skipWhitespace(read())) != ')')
0854:                        throw error(L.l("expected `{0}' at {1}", ")",
0855:                                badChar(ch)));
0856:
0857:                    return expr;
0858:                }
0859:
0860:                case '/':
0861:                case '@':
0862:                case '*':
0863:                    unread();
0864:                    return NodeSetExpr.create(parseUnion(parseBasisTop(parent),
0865:                            parent));
0866:
0867:                case '\'':
0868:                case '"': {
0869:                    int end = ch;
0870:                    CharBuffer cb = new CharBuffer();
0871:                    for (ch = read(); ch >= 0; ch = read()) {
0872:                        if (ch != end)
0873:                            cb.append((char) ch);
0874:                        else if ((ch = read()) == end)
0875:                            cb.append((char) ch);
0876:                        else {
0877:                            unread();
0878:                            break;
0879:                        }
0880:                    }
0881:
0882:                    return new StringExpr(cb.toString());
0883:                }
0884:
0885:                case '$': {
0886:                    String name = readName(read());
0887:                    return new VarExpr(name);
0888:                }
0889:
0890:                default:
0891:                    if (!XmlChar.isNameStart(ch))
0892:                        throw error(L
0893:                                .l("unknown character at {0}", badChar(ch)));
0894:
0895:                    String name = readName(ch);
0896:
0897:                    ch = skipWhitespace(read());
0898:                    int axisIndex = name.indexOf("::");
0899:
0900:                    // make sure axis are treated as node sets
0901:                    if (ch == '(' && axisIndex < 0) {
0902:                        return parseFunction(parent, listParent, name, true);
0903:                    } else if (ch == '(') {
0904:                        String axis = name.substring(0, axisIndex);
0905:                        if (axisMap.get(axis) <= 0)
0906:                            return parseFunction(parent, listParent, name, true);
0907:                    }
0908:
0909:                    unread();
0910:
0911:                    if (parent == null)
0912:                        parent = new FromContext();
0913:                    return parseNodeSetExpr(parent, name, Node.ELEMENT_NODE);
0914:                }
0915:            }
0916:
0917:            /**
0918:             * function ::= name '(' args ')'
0919:             *
0920:             * The XPath library functions are hard-coded for a little extra
0921:             * execution efficiency.
0922:             */
0923:            Expr parseFunction(AbstractPattern parent,
0924:                    AbstractPattern listParent, String name,
0925:                    boolean fromChildren) throws XPathParseException {
0926:                int ch = skipWhitespace(read());
0927:
0928:                ArrayList<Expr> args = new ArrayList<Expr>();
0929:
0930:                for (; ch >= 0 && ch != ')'; ch = skipWhitespace(read())) {
0931:                    if (ch != ',')
0932:                        unread();
0933:                    Expr expr = parseExpr(parent, listParent);
0934:
0935:                    if (expr == null)
0936:                        throw error(L.l("null expression"));
0937:
0938:                    args.add(expr);
0939:                }
0940:
0941:                int code = exprFunctions.get(name);
0942:                switch (code) {
0943:                case Expr.TRUE:
0944:                case Expr.FALSE:
0945:                case Expr.NOT:
0946:                case Expr.BOOLEAN:
0947:                case Expr.STARTS_WITH:
0948:                case Expr.CONTAINS:
0949:                case Expr.LANG:
0950:                case Expr.FUNCTION_AVAILABLE:
0951:                    return new BooleanExpr(code, args);
0952:
0953:                case Expr.NUMBER:
0954:                case Expr.FLOOR:
0955:                case Expr.CEILING:
0956:                case Expr.ROUND:
0957:                case Expr.STRING_LENGTH:
0958:                    return new NumericExpr(code, args);
0959:
0960:                case Expr.POSITION:
0961:                case Expr.LAST:
0962:                    return new NumericExpr(code, listParent);
0963:
0964:                case Expr.COUNT:
0965:                case Expr.SUM:
0966:                    if (args.size() == 0)
0967:                        args.add(NodeSetExpr.create(new FromContext()));
0968:                    return new NumericExpr(code, ((Expr) args.get(0))
0969:                            .toNodeList());
0970:
0971:                case Expr.CONCAT:
0972:                case Expr.SUBSTRING_BEFORE:
0973:                case Expr.SUBSTRING:
0974:                case Expr.SUBSTRING_AFTER:
0975:                case Expr.TRANSLATE:
0976:                case Expr.SYSTEM_PROPERTY:
0977:                    return new StringExpr(code, args);
0978:
0979:                case Expr.STRING:
0980:                case Expr.NORMALIZE:
0981:                    return new StringExpr(code, args);
0982:
0983:                case Expr.LOCAL_PART:
0984:                case Expr.NAMESPACE:
0985:                case Expr.QNAME:
0986:                case Expr.GENERATE_ID:
0987:                    if (args.size() == 0)
0988:                        args.add(NodeSetExpr.create(new FromContext()));
0989:                    return new StringExpr(code, args);
0990:
0991:                case Expr.ID:
0992:                    if (args.size() == 0) {
0993:                        args.add(NodeSetExpr.create(parent));
0994:                        return new IdExpr(args);
0995:                    } else
0996:                        return new IdExpr(args);
0997:
0998:                case Expr.IF:
0999:                    if (args.size() != 3)
1000:                        throw error(L.l("`if' needs three args."));
1001:
1002:                    return new ObjectExpr(code, args);
1003:
1004:                case Expr.BASE_URI:
1005:                    if (args.size() != 1)
1006:                        throw error(L.l("`base-uri' needs one args."));
1007:
1008:                    return new StringExpr(code, args.get(0));
1009:
1010:                case TEXT:
1011:                    if (fromChildren)
1012:                        parent = new FromChildren(parent);
1013:                    AbstractPattern pattern = NodeTypePattern.create(parent,
1014:                            Node.TEXT_NODE);
1015:                    return NodeSetExpr.create(pattern);
1016:
1017:                case COMMENT:
1018:                    if (fromChildren)
1019:                        parent = new FromChildren(parent);
1020:                    pattern = NodeTypePattern.create(parent, Node.COMMENT_NODE);
1021:                    return NodeSetExpr.create(pattern);
1022:
1023:                case ER:
1024:                    if (fromChildren)
1025:                        parent = new FromChildren(parent);
1026:                    pattern = NodeTypePattern.create(parent,
1027:                            Node.ENTITY_REFERENCE_NODE);
1028:                    return NodeSetExpr.create(pattern);
1029:
1030:                case PI:
1031:                    if (fromChildren)
1032:                        parent = new FromChildren(parent);
1033:                    if (args.size() == 1) {
1034:                        Expr expr = (Expr) args.get(0);
1035:                        String value = null;
1036:                        if (expr instanceof  StringExpr)
1037:                            value = ((StringExpr) expr).getValue();
1038:                        if (value == null)
1039:                            throw error(L
1040:                                    .l("processing-instruction expects string literal"));
1041:                        pattern = new NodePattern(parent, value,
1042:                                Node.PROCESSING_INSTRUCTION_NODE);
1043:                    } else
1044:                        pattern = NodeTypePattern.create(parent,
1045:                                Node.PROCESSING_INSTRUCTION_NODE);
1046:                    return NodeSetExpr.create(pattern);
1047:
1048:                case NODE:
1049:                    if (fromChildren)
1050:                        parent = new FromChildren(parent);
1051:                    pattern = NodeTypePattern.create(parent,
1052:                            NodeTypePattern.NODE);
1053:                    return NodeSetExpr.create(pattern);
1054:
1055:                case CURRENT:
1056:                    return NodeSetExpr.create(new CurrentPattern());
1057:
1058:                case CONTEXT:
1059:                    return NodeSetExpr.create(new FromContext());
1060:
1061:                default:
1062:                    Expr function = constructorFunction(name, args);
1063:
1064:                    if (function != null)
1065:                        return function;
1066:
1067:                    int p = name.lastIndexOf(':');
1068:                    String prefix;
1069:
1070:                    if (p > 0)
1071:                        prefix = name.substring(0, p);
1072:                    else
1073:                        prefix = "";
1074:
1075:                    String context = NamespaceContext.find(_namespace, prefix);
1076:
1077:                    if (context == null) {
1078:                    } else if (context.startsWith("java:"))
1079:                        name = context + "." + name.substring(p + 1);
1080:                    else if (context.indexOf(':') < 0)
1081:                        name = "java:" + context + "." + name.substring(p + 1);
1082:
1083:                    if (name.startsWith("java:")) {
1084:                        p = name.lastIndexOf('.');
1085:                        if (p < 0)
1086:                            throw error(L
1087:                                    .l(
1088:                                            "`{0}' is an illegal extension function.  Java extension functions must look like java:mypkg.MyClass.mymethod.",
1089:                                            name));
1090:
1091:                        String className = name.substring(5, p);
1092:                        String methodName = name.substring(p + 1);
1093:
1094:                        Class cl;
1095:                        try {
1096:                            cl = CauchoSystem.loadClass(className);
1097:                        } catch (ClassNotFoundException e) {
1098:                            throw error(L
1099:                                    .l(
1100:                                            "`{0}' is an unknown Java class.  Java extension functions must use public classes.",
1101:                                            className));
1102:                        }
1103:
1104:                        if (methodName.equals("new")) {
1105:                            Constructor[] constructors = cl.getConstructors();
1106:
1107:                            for (int i = 0; i < constructors.length; i++) {
1108:                                if (constructors[i].getParameterTypes().length == args
1109:                                        .size())
1110:                                    return new NewJavaExpr(constructors[i],
1111:                                            args);
1112:                            }
1113:
1114:                            throw error(L.l(
1115:                                    "No matching public constructor in `{0}'",
1116:                                    className));
1117:                        }
1118:
1119:                        Method method = null;
1120:                        Method[] methods = cl.getMethods();
1121:
1122:                        if (args.size() > 0) {
1123:                            for (int i = 0; i < methods.length; i++) {
1124:                                if (methods[i].getName().equals(methodName)
1125:                                        && methods[i].getParameterTypes().length == args
1126:                                                .size() - 1
1127:                                        && !Modifier.isStatic(methods[i]
1128:                                                .getModifiers())) {
1129:                                    Expr objArg = (Expr) args.remove(0);
1130:
1131:                                    return new ObjectJavaExpr(methods[i],
1132:                                            objArg, args);
1133:                                }
1134:                            }
1135:                        }
1136:
1137:                        for (int i = 0; i < methods.length; i++) {
1138:                            if (methods[i].getName().equals(methodName)
1139:                                    && methods[i].getParameterTypes().length == args
1140:                                            .size()) {
1141:                                method = methods[i];
1142:                                break;
1143:                            }
1144:                        }
1145:
1146:                        if (method == null)
1147:                            throw error(L
1148:                                    .l(
1149:                                            "`{0}' does not match a public method in `{1}'",
1150:                                            methodName, className));
1151:
1152:                        if (!Modifier.isStatic(method.getModifiers()))
1153:                            throw error(L.l(
1154:                                    "`{0}' is not a static method in `{1}'",
1155:                                    methodName, className));
1156:
1157:                        return new StaticJavaExpr(method, args);
1158:                    } else if (name.equals(""))
1159:                        throw error(L.l("expected node-test at `{0}'", "("));
1160:
1161:                    return new FunExpr(name, parent, args);
1162:                }
1163:            }
1164:
1165:            private Expr constructorFunction(String name, ArrayList<Expr> args)
1166:                    throws XPathParseException {
1167:                Constructor constructor = _exprFunctions.get(name);
1168:
1169:                if (constructor == null)
1170:                    return null;
1171:
1172:                Class[] params = constructor.getParameterTypes();
1173:
1174:                if (params.length < args.size())
1175:                    throw error(L.l("`{0}' needs {1} arguments", name, ""
1176:                            + params.length));
1177:
1178:                Object[] values = new Object[params.length];
1179:
1180:                for (int i = 0; i < args.size(); i++)
1181:                    values[i] = args.get(i);
1182:
1183:                try {
1184:                    return (Expr) constructor.newInstance(values);
1185:                } catch (Throwable e) {
1186:                    throw new XPathParseException(e);
1187:                }
1188:            }
1189:
1190:            private Expr parseNodeSetExpr(AbstractPattern parent, String name,
1191:                    int nodeType) throws XPathParseException {
1192:                AbstractPattern top = parseAxis(parent, name, true, nodeType);
1193:                top = parseFilter(top);
1194:
1195:                return NodeSetExpr.create(parseUnion(parsePath(top), parent));
1196:            }
1197:
1198:            /**
1199:             * Scans the next token.
1200:             *
1201:             * @return token code, expressed as an Expr enumeration.
1202:             */
1203:            private int scanToken() throws XPathParseException {
1204:                if (peek >= 0) {
1205:                    int value = peek;
1206:                    peek = -1;
1207:                    return value;
1208:                }
1209:
1210:                int ch = skipWhitespace(read());
1211:
1212:                switch (ch) {
1213:                case '+':
1214:                    return Expr.ADD;
1215:                case '-':
1216:                    return Expr.SUB;
1217:                case '*':
1218:                    return Expr.MUL;
1219:                case '=':
1220:                    return Expr.EQ;
1221:
1222:                case '!':
1223:                    ch = read();
1224:                    if (ch == '=')
1225:                        return Expr.NEQ;
1226:                    else
1227:                        throw error(L.l("expected `{0}' at {1}", "=",
1228:                                badChar(ch)));
1229:
1230:                case '<':
1231:                    ch = read();
1232:                    if (ch == '=')
1233:                        return Expr.LE;
1234:                    else {
1235:                        unread();
1236:                        return Expr.LT;
1237:                    }
1238:
1239:                case '>':
1240:                    ch = read();
1241:                    if (ch == '=')
1242:                        return Expr.GE;
1243:                    else {
1244:                        unread();
1245:                        return Expr.GT;
1246:                    }
1247:
1248:                default:
1249:                    if (XmlChar.isNameStart(ch)) {
1250:                        String name = readName(ch);
1251:
1252:                        if (name.equals("div"))
1253:                            return Expr.DIV;
1254:                        else if (name.equals("quo"))
1255:                            return Expr.QUO;
1256:                        else if (name.equals("mod"))
1257:                            return Expr.MOD;
1258:                        else if (name.equals("and"))
1259:                            return Expr.AND;
1260:                        else if (name.equals("or"))
1261:                            return Expr.OR;
1262:                        else
1263:                            throw error(L.l(
1264:                                    "expected binary operation at `{0}'", name));
1265:                    }
1266:
1267:                    unread();
1268:                    return -1;
1269:                }
1270:            }
1271:
1272:            private String readName(int ch) {
1273:                tag.clear();
1274:                for (; XmlChar.isNameChar(ch); ch = read())
1275:                    tag.append((char) ch);
1276:
1277:                if (ch == '*' && tag.endsWith(":"))
1278:                    tag.append((char) ch);
1279:                else
1280:                    unread();
1281:
1282:                return tag.toString();
1283:            }
1284:
1285:            private void undoToken(int token) {
1286:                peek = token;
1287:            }
1288:
1289:            private int read() {
1290:                if (index < _string.length()) {
1291:                    return _string.charAt(index++);
1292:                } else {
1293:                    index++;
1294:                    return -1;
1295:                }
1296:            }
1297:
1298:            private void unread() {
1299:                index--;
1300:            }
1301:
1302:            private XPathParseException error(String message) {
1303:                return new XPathParseException(message + " in " + _string);
1304:            }
1305:
1306:            private String badChar(int ch) {
1307:                if (ch < 0)
1308:                    return L.l("end of file");
1309:                else if (ch == '\n')
1310:                    return L.l("end of line");
1311:                else
1312:                    return "`" + (char) ch + "'";
1313:            }
1314:
1315:            private int skipWhitespace(int ch) throws XPathParseException {
1316:                for (; ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'; ch = read()) {
1317:                }
1318:
1319:                return ch;
1320:            }
1321:
1322:            private static void addFunction(String name, Class cl) {
1323:                Constructor[] constructors = cl.getConstructors();
1324:
1325:                _exprFunctions.put(name, constructors[0]);
1326:            }
1327:
1328:            static {
1329:                exprFunctions = new IntMap();
1330:                exprFunctions.put("id", Expr.ID);
1331:
1332:                exprFunctions.put("true", Expr.TRUE);
1333:                exprFunctions.put("false", Expr.FALSE);
1334:                exprFunctions.put("not", Expr.NOT);
1335:                exprFunctions.put("boolean", Expr.BOOLEAN);
1336:                exprFunctions.put("starts-with", Expr.STARTS_WITH);
1337:                exprFunctions.put("contains", Expr.CONTAINS);
1338:                exprFunctions.put("lang", Expr.LANG);
1339:
1340:                exprFunctions.put("number", Expr.NUMBER);
1341:                exprFunctions.put("sum", Expr.SUM);
1342:                exprFunctions.put("floor", Expr.FLOOR);
1343:                exprFunctions.put("ceiling", Expr.CEILING);
1344:                exprFunctions.put("round", Expr.ROUND);
1345:                exprFunctions.put("position", Expr.POSITION);
1346:                exprFunctions.put("count", Expr.COUNT);
1347:                exprFunctions.put("last", Expr.LAST);
1348:                exprFunctions.put("string-length", Expr.STRING_LENGTH);
1349:
1350:                exprFunctions.put("string", Expr.STRING);
1351:                exprFunctions.put("concat", Expr.CONCAT);
1352:                exprFunctions.put("substring", Expr.SUBSTRING);
1353:                exprFunctions.put("substring-before", Expr.SUBSTRING_BEFORE);
1354:                exprFunctions.put("substring-after", Expr.SUBSTRING_AFTER);
1355:                exprFunctions.put("normalize-space", Expr.NORMALIZE);
1356:                exprFunctions.put("translate", Expr.TRANSLATE);
1357:
1358:                exprFunctions.put("local-name", Expr.LOCAL_PART);
1359:                exprFunctions.put("local-part", Expr.LOCAL_PART);
1360:                exprFunctions.put("namespace-uri", Expr.NAMESPACE);
1361:                exprFunctions.put("name", Expr.QNAME);
1362:                exprFunctions.put("generate-id", Expr.GENERATE_ID);
1363:
1364:                exprFunctions.put("if", Expr.IF);
1365:
1366:                exprFunctions.put("text", TEXT);
1367:                exprFunctions.put("comment", COMMENT);
1368:                exprFunctions.put("er", ER);
1369:                exprFunctions.put("entity-reference", ER);
1370:                exprFunctions.put("pi", PI);
1371:                exprFunctions.put("processing-instruction", PI);
1372:                exprFunctions.put("node", NODE);
1373:                exprFunctions.put("current", CURRENT);
1374:                exprFunctions.put("context", CONTEXT);
1375:
1376:                axisMap = new IntMap();
1377:                axisMap.put("ancestor", ANCESTOR_AXIS);
1378:                axisMap.put("ancestor-or-self", ANCESTOR_OR_SELF_AXIS);
1379:                axisMap.put("attribute", ATTRIBUTE_AXIS);
1380:                axisMap.put("child", CHILD_AXIS);
1381:                axisMap.put("descendant", DESCENDANT_AXIS);
1382:                axisMap.put("descendant-or-self", DESCENDANT_OR_SELF_AXIS);
1383:                axisMap.put("following", FOLLOWING_AXIS);
1384:                axisMap.put("following-sibling", FOLLOWING_SIBLING_AXIS);
1385:                axisMap.put("namespace", NAMESPACE_AXIS);
1386:                axisMap.put("parent", PARENT_AXIS);
1387:                axisMap.put("preceding", PRECEDING_AXIS);
1388:                axisMap.put("preceding-sibling", PRECEDING_SIBLING_AXIS);
1389:                axisMap.put("self", SELF_AXIS);
1390:
1391:                _exprFunctions = new HashMap<String, Constructor>();
1392:                addFunction("fn:base-uri", BaseURI.class);
1393:                addFunction("fn:resolve-uri", ResolveURI.class);
1394:                addFunction("fn:trace", Trace.class);
1395:            }
1396:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.