1 57 58 package com.sun.org.apache.xerces.internal.impl.xpath; 59 60 import java.util.Vector ; 61 62 import com.sun.org.apache.xerces.internal.util.SymbolTable; 63 import com.sun.org.apache.xerces.internal.util.XMLSymbols; 64 import com.sun.org.apache.xerces.internal.util.XMLChar; 65 import com.sun.org.apache.xerces.internal.xni.NamespaceContext; 66 import com.sun.org.apache.xerces.internal.xni.QName; 67 68 74 public class XPath { 75 76 80 private static final boolean DEBUG_ALL = false; 81 82 private static final boolean DEBUG_XPATH_PARSE = DEBUG_ALL || false; 83 84 private static final boolean DEBUG_ANY = DEBUG_XPATH_PARSE; 85 86 90 91 protected String fExpression; 92 93 94 protected SymbolTable fSymbolTable; 95 96 97 protected LocationPath[] fLocationPaths; 98 99 103 104 public XPath(String xpath, SymbolTable symbolTable, 105 NamespaceContext context) 106 throws XPathException { 107 fExpression = xpath; 108 fSymbolTable = symbolTable; 109 parseExpression(context); 110 } 112 116 120 public LocationPath[] getLocationPaths() { 121 LocationPath[] ret=new LocationPath[fLocationPaths.length]; 122 for (int i=0;i<fLocationPaths.length;i++){ 123 ret[i]=(LocationPath)fLocationPaths[i].clone(); 124 } 125 return ret; 126 } 128 129 public LocationPath getLocationPath() { 130 return (LocationPath)fLocationPaths[0].clone(); 131 } 133 137 138 public String toString() { 139 StringBuffer buf=new StringBuffer (); 140 for (int i=0;i<fLocationPaths.length;i++){ 141 if (i>0){ 142 buf.append("|"); 143 } 144 buf.append(fLocationPaths[i].toString()); 145 } 146 return buf.toString(); 147 } 149 153 160 private static void check( boolean b ) throws XPathException { 161 if(!b) throw new XPathException("c-general-xpath"); 162 } 163 164 169 private LocationPath buildLocationPath( Vector stepsVector ) throws XPathException { 170 int size = stepsVector.size(); 171 check(size!=0); 172 Step[] steps = new Step[size]; 173 stepsVector.copyInto(steps); 174 stepsVector.removeAllElements(); 175 176 return new LocationPath(steps); 177 } 178 179 183 private void parseExpression(final NamespaceContext context) 184 throws XPathException { 185 186 final XPath.Tokens xtokens = new XPath.Tokens(fSymbolTable); 188 189 XPath.Scanner scanner = new XPath.Scanner(fSymbolTable) { 191 protected void addToken(XPath.Tokens tokens, int token) 192 throws XPathException { 193 if ( 194 token == XPath.Tokens.EXPRTOKEN_ATSIGN || 195 token == XPath.Tokens.EXPRTOKEN_NAMETEST_QNAME || 196 token == XPath.Tokens.EXPRTOKEN_OPERATOR_SLASH || 197 token == XPath.Tokens.EXPRTOKEN_PERIOD || 198 token == XPath.Tokens.EXPRTOKEN_NAMETEST_ANY || 199 token == XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE || 200 token == XPath.Tokens.EXPRTOKEN_OPERATOR_DOUBLE_SLASH || 201 token == XPath.Tokens.EXPRTOKEN_OPERATOR_UNION 202 ) { 204 super.addToken(tokens, token); 205 return; 206 } 207 throw new XPathException("c-general-xpath"); 208 } 209 }; 210 211 int length = fExpression.length(); 212 213 boolean success = scanner.scanExpr(fSymbolTable, 214 xtokens, fExpression, 0, length); 215 if(!success) 216 throw new XPathException("c-general-xpath"); 217 218 Vector stepsVector = new Vector (); 220 Vector locationPathsVector= new Vector (); 221 222 boolean expectingStep = true; 229 230 while(xtokens.hasMore()) { 231 final int token = xtokens.nextToken(); 232 233 switch (token) { 234 case XPath.Tokens.EXPRTOKEN_OPERATOR_UNION :{ 235 check(!expectingStep); 236 locationPathsVector.addElement(buildLocationPath(stepsVector)); 237 expectingStep=true; 238 break; 239 } 240 241 case XPath.Tokens.EXPRTOKEN_ATSIGN: { 242 check(expectingStep); 243 Step step = new Step( 244 new Axis(Axis.ATTRIBUTE), 245 parseNodeTest(xtokens.nextToken(),xtokens,context)); 246 stepsVector.addElement(step); 247 expectingStep=false; 248 break; 249 } 250 case XPath.Tokens.EXPRTOKEN_NAMETEST_ANY: 251 case XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE: 252 case XPath.Tokens.EXPRTOKEN_NAMETEST_QNAME: { 253 check(expectingStep); 254 Step step = new Step( 255 new Axis(Axis.CHILD), 256 parseNodeTest(token,xtokens,context)); 257 stepsVector.addElement(step); 258 expectingStep=false; 259 break; 260 } 261 262 case XPath.Tokens.EXPRTOKEN_PERIOD: { 263 check(expectingStep); 264 expectingStep=false; 265 266 if (stepsVector.size()==0) { 272 Axis axis = new Axis(Axis.SELF); 274 NodeTest nodeTest = new NodeTest(NodeTest.NODE); 275 Step step = new Step(axis, nodeTest); 276 stepsVector.addElement(step); 277 278 if( xtokens.hasMore() 279 && xtokens.peekToken() == XPath.Tokens.EXPRTOKEN_OPERATOR_DOUBLE_SLASH){ 280 xtokens.nextToken(); 282 283 axis = new Axis(Axis.DESCENDANT); 285 nodeTest = new NodeTest(NodeTest.NODE); 286 step = new Step(axis, nodeTest); 287 stepsVector.addElement(step); 288 expectingStep=true; 289 } 290 } 291 break; 292 } 293 294 case XPath.Tokens.EXPRTOKEN_OPERATOR_DOUBLE_SLASH:{ 295 throw new XPathException("c-general-xpath"); 299 } 300 case XPath.Tokens.EXPRTOKEN_OPERATOR_SLASH: { 301 check(!expectingStep); 302 expectingStep=true; 303 break; 304 } 305 default: 306 throw new InternalError (); 308 } 309 } 310 311 check(!expectingStep); 312 313 locationPathsVector.addElement(buildLocationPath(stepsVector)); 314 315 fLocationPaths=new LocationPath[locationPathsVector.size()]; 317 locationPathsVector.copyInto(fLocationPaths); 318 319 320 if (DEBUG_XPATH_PARSE) { 321 System.out.println(">>> "+fLocationPaths); 322 } 323 324 } 326 330 private NodeTest parseNodeTest( int typeToken, Tokens xtokens, NamespaceContext context ) 331 throws XPathException { 332 switch(typeToken) { 333 case XPath.Tokens.EXPRTOKEN_NAMETEST_ANY: 334 return new NodeTest(NodeTest.WILDCARD); 335 336 case XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE: 337 case XPath.Tokens.EXPRTOKEN_NAMETEST_QNAME: 338 String prefix = xtokens.nextTokenAsString(); 340 String uri = null; 341 if (context != null && prefix != XMLSymbols.EMPTY_STRING) { 342 uri = context.getURI(prefix); 343 } 344 if (prefix != XMLSymbols.EMPTY_STRING && context != null && uri == null) { 345 throw new XPathException("c-general-xpath-ns"); 346 } 347 348 if (typeToken==XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE) 349 return new NodeTest(prefix,uri); 350 351 String localpart = xtokens.nextTokenAsString(); 352 String rawname = prefix != XMLSymbols.EMPTY_STRING 353 ? fSymbolTable.addSymbol(prefix+':'+localpart) 354 : localpart; 355 356 return new NodeTest(new QName(prefix, localpart, rawname, uri)); 357 358 default: 359 throw new InternalError (); 361 } 362 } 363 364 365 369 371 376 public static class LocationPath 377 implements Cloneable { 378 379 383 384 public Step[] steps; 385 386 390 391 public LocationPath(Step[] steps) { 392 this.steps = steps; 393 } 395 396 protected LocationPath(LocationPath path) { 397 steps = new Step[path.steps.length]; 398 for (int i = 0; i < steps.length; i++) { 399 steps[i] = (Step)path.steps[i].clone(); 400 } 401 } 403 407 408 public String toString() { 409 StringBuffer str = new StringBuffer (); 410 for (int i = 0; i < steps.length; i++) { 411 if (i > 0 && (steps[i-1].axis.type!=Axis.DESCENDANT 412 && steps[i].axis.type!=Axis.DESCENDANT) ){ 413 str.append('/'); 414 } 415 str.append(steps[i].toString()); 416 } 417 if (false) { 421 str.append('['); 422 String s = super.toString(); 423 str.append(s.substring(s.indexOf('@'))); 424 str.append(']'); 425 } 426 return str.toString(); 427 } 429 430 public Object clone() { 431 return new LocationPath(this); 432 } 434 } 436 441 public static class Step 442 implements Cloneable { 443 444 448 449 public Axis axis; 450 451 452 public NodeTest nodeTest; 453 454 458 459 public Step(Axis axis, NodeTest nodeTest) { 460 this.axis = axis; 461 this.nodeTest = nodeTest; 462 } 464 465 protected Step(Step step) { 466 axis = (Axis)step.axis.clone(); 467 nodeTest = (NodeTest)step.nodeTest.clone(); 468 } 470 474 475 public String toString() { 476 if (axis.type == Axis.SELF) { 477 return "."; 478 } 479 if (axis.type == Axis.ATTRIBUTE) { 480 return "@" + nodeTest.toString(); 481 } 482 if (axis.type == Axis.CHILD) { 483 return nodeTest.toString(); 484 } 485 if (axis.type == Axis.DESCENDANT) { 486 return "//"; 487 } 488 return "??? ("+axis.type+')'; 489 } 491 492 public Object clone() { 493 return new Step(this); 494 } 496 } 498 503 public static class Axis 504 implements Cloneable { 505 506 510 511 public static final short CHILD = 1; 512 513 514 public static final short ATTRIBUTE = 2; 515 516 517 public static final short SELF = 3; 518 519 520 521 public static final short DESCENDANT = 4; 522 526 527 public short type; 528 529 533 534 public Axis(short type) { 535 this.type = type; 536 } 538 539 protected Axis(Axis axis) { 540 type = axis.type; 541 } 543 547 548 public String toString() { 549 switch (type) { 550 case CHILD: return "child"; 551 case ATTRIBUTE: return "attribute"; 552 case SELF: return "self"; 553 case DESCENDANT: return "descendant"; 554 } 555 return "???"; 556 } 558 559 public Object clone() { 560 return new Axis(this); 561 } 563 } 565 570 public static class NodeTest 571 implements Cloneable { 572 573 577 578 public static final short QNAME = 1; 579 580 581 public static final short WILDCARD = 2; 582 583 584 public static final short NODE = 3; 585 586 587 public static final short NAMESPACE= 4; 588 589 593 594 public short type; 595 596 597 public final QName name = new QName(); 598 599 603 604 public NodeTest(short type) { 605 this.type = type; 606 } 608 609 public NodeTest(QName name) { 610 this.type = QNAME; 611 this.name.setValues(name); 612 } 614 public NodeTest(String prefix, String uri) { 615 this.type = NAMESPACE; 616 this.name.setValues(prefix, null, null, uri); 617 } 619 620 public NodeTest(NodeTest nodeTest) { 621 type = nodeTest.type; 622 name.setValues(nodeTest.name); 623 } 625 629 630 public String toString() { 631 632 switch (type) { 633 case QNAME: { 634 if (name.prefix.length() !=0) { 635 if (name.uri != null) { 636 return name.prefix+':'+name.localpart; 637 } 638 return "{"+name.uri+'}'+name.prefix+':'+name.localpart; 639 } 640 return name.localpart; 641 } 642 case NAMESPACE: { 643 if (name.prefix.length() !=0) { 644 if (name.uri != null) { 645 return name.prefix+":*"; 646 } 647 return "{"+name.uri+'}'+name.prefix+":*"; 648 } 649 return "???:*"; 650 } 651 case WILDCARD: { 652 return "*"; 653 } 654 case NODE: { 655 return "node()"; 656 } 657 } 658 return "???"; 659 660 } 662 663 public Object clone() { 664 return new NodeTest(this); 665 } 667 } 669 671 677 685 private static final class Tokens { 686 687 static final boolean DUMP_TOKENS = false; 688 689 694 public static final int 695 EXPRTOKEN_OPEN_PAREN = 0, 696 EXPRTOKEN_CLOSE_PAREN = 1, 697 EXPRTOKEN_OPEN_BRACKET = 2, 698 EXPRTOKEN_CLOSE_BRACKET = 3, 699 EXPRTOKEN_PERIOD = 4, 700 EXPRTOKEN_DOUBLE_PERIOD = 5, 701 EXPRTOKEN_ATSIGN = 6, 702 EXPRTOKEN_COMMA = 7, 703 EXPRTOKEN_DOUBLE_COLON = 8, 704 EXPRTOKEN_NAMETEST_ANY = 9, 710 EXPRTOKEN_NAMETEST_NAMESPACE = 10, 711 EXPRTOKEN_NAMETEST_QNAME = 11, 712 EXPRTOKEN_NODETYPE_COMMENT = 12, 716 EXPRTOKEN_NODETYPE_TEXT = 13, 717 EXPRTOKEN_NODETYPE_PI = 14, 718 EXPRTOKEN_NODETYPE_NODE = 15, 719 EXPRTOKEN_OPERATOR_AND = 16, 727 EXPRTOKEN_OPERATOR_OR = 17, 728 EXPRTOKEN_OPERATOR_MOD = 18, 729 EXPRTOKEN_OPERATOR_DIV = 19, 730 EXPRTOKEN_OPERATOR_MULT = 20, 731 EXPRTOKEN_OPERATOR_SLASH = 21, 732 EXPRTOKEN_OPERATOR_DOUBLE_SLASH = 22, 733 EXPRTOKEN_OPERATOR_UNION = 23, 734 EXPRTOKEN_OPERATOR_PLUS = 24, 735 EXPRTOKEN_OPERATOR_MINUS = 25, 736 EXPRTOKEN_OPERATOR_EQUAL = 26, 737 EXPRTOKEN_OPERATOR_NOT_EQUAL = 27, 738 EXPRTOKEN_OPERATOR_LESS = 28, 739 EXPRTOKEN_OPERATOR_LESS_EQUAL = 29, 740 EXPRTOKEN_OPERATOR_GREATER = 30, 741 EXPRTOKEN_OPERATOR_GREATER_EQUAL = 31, 742 743 746 EXPRTOKEN_FUNCTION_NAME = 32, 752 EXPRTOKEN_AXISNAME_ANCESTOR = 33, 764 EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF = 34, 765 EXPRTOKEN_AXISNAME_ATTRIBUTE = 35, 766 EXPRTOKEN_AXISNAME_CHILD = 36, 767 EXPRTOKEN_AXISNAME_DESCENDANT = 37, 768 EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF = 38, 769 EXPRTOKEN_AXISNAME_FOLLOWING = 39, 770 EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING = 40, 771 EXPRTOKEN_AXISNAME_NAMESPACE = 41, 772 EXPRTOKEN_AXISNAME_PARENT = 42, 773 EXPRTOKEN_AXISNAME_PRECEDING = 43, 774 EXPRTOKEN_AXISNAME_PRECEDING_SIBLING = 44, 775 EXPRTOKEN_AXISNAME_SELF = 45, 776 EXPRTOKEN_LITERAL = 46, 782 EXPRTOKEN_NUMBER = 47, 789 EXPRTOKEN_VARIABLE_REFERENCE = 48; 795 796 private static final String [] fgTokenNames = { 797 "EXPRTOKEN_OPEN_PAREN", 798 "EXPRTOKEN_CLOSE_PAREN", 799 "EXPRTOKEN_OPEN_BRACKET", 800 "EXPRTOKEN_CLOSE_BRACKET", 801 "EXPRTOKEN_PERIOD", 802 "EXPRTOKEN_DOUBLE_PERIOD", 803 "EXPRTOKEN_ATSIGN", 804 "EXPRTOKEN_COMMA", 805 "EXPRTOKEN_DOUBLE_COLON", 806 "EXPRTOKEN_NAMETEST_ANY", 807 "EXPRTOKEN_NAMETEST_NAMESPACE", 808 "EXPRTOKEN_NAMETEST_QNAME", 809 "EXPRTOKEN_NODETYPE_COMMENT", 810 "EXPRTOKEN_NODETYPE_TEXT", 811 "EXPRTOKEN_NODETYPE_PI", 812 "EXPRTOKEN_NODETYPE_NODE", 813 "EXPRTOKEN_OPERATOR_AND", 814 "EXPRTOKEN_OPERATOR_OR", 815 "EXPRTOKEN_OPERATOR_MOD", 816 "EXPRTOKEN_OPERATOR_DIV", 817 "EXPRTOKEN_OPERATOR_MULT", 818 "EXPRTOKEN_OPERATOR_SLASH", 819 "EXPRTOKEN_OPERATOR_DOUBLE_SLASH", 820 "EXPRTOKEN_OPERATOR_UNION", 821 "EXPRTOKEN_OPERATOR_PLUS", 822 "EXPRTOKEN_OPERATOR_MINUS", 823 "EXPRTOKEN_OPERATOR_EQUAL", 824 "EXPRTOKEN_OPERATOR_NOT_EQUAL", 825 "EXPRTOKEN_OPERATOR_LESS", 826 "EXPRTOKEN_OPERATOR_LESS_EQUAL", 827 "EXPRTOKEN_OPERATOR_GREATER", 828 "EXPRTOKEN_OPERATOR_GREATER_EQUAL", 829 "EXPRTOKEN_FUNCTION_NAME", 830 "EXPRTOKEN_AXISNAME_ANCESTOR", 831 "EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF", 832 "EXPRTOKEN_AXISNAME_ATTRIBUTE", 833 "EXPRTOKEN_AXISNAME_CHILD", 834 "EXPRTOKEN_AXISNAME_DESCENDANT", 835 "EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF", 836 "EXPRTOKEN_AXISNAME_FOLLOWING", 837 "EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING", 838 "EXPRTOKEN_AXISNAME_NAMESPACE", 839 "EXPRTOKEN_AXISNAME_PARENT", 840 "EXPRTOKEN_AXISNAME_PRECEDING", 841 "EXPRTOKEN_AXISNAME_PRECEDING_SIBLING", 842 "EXPRTOKEN_AXISNAME_SELF", 843 "EXPRTOKEN_LITERAL", 844 "EXPRTOKEN_NUMBER", 845 "EXPRTOKEN_VARIABLE_REFERENCE" 846 }; 847 848 851 private static final int INITIAL_TOKEN_COUNT = 1 << 8; 852 private int[] fTokens = new int[INITIAL_TOKEN_COUNT]; 853 private int fTokenCount = 0; 855 private SymbolTable fSymbolTable; 856 857 private java.util.Hashtable fSymbolMapping = new java.util.Hashtable (); 859 860 private java.util.Hashtable fTokenNames = new java.util.Hashtable (); 862 863 866 private int fCurrentTokenIndex; 867 868 872 public Tokens(SymbolTable symbolTable) { 873 fSymbolTable = symbolTable; 874 final String [] symbols = { 875 "ancestor", "ancestor-or-self", "attribute", 876 "child", "descendant", "descendant-or-self", 877 "following", "following-sibling", "namespace", 878 "parent", "preceding", "preceding-sibling", 879 "self", 880 }; 881 for (int i = 0; i < symbols.length; i++) { 882 fSymbolMapping.put(fSymbolTable.addSymbol(symbols[i]), new Integer (i)); 883 } 884 fTokenNames.put(new Integer (EXPRTOKEN_OPEN_PAREN), "EXPRTOKEN_OPEN_PAREN"); 885 fTokenNames.put(new Integer (EXPRTOKEN_CLOSE_PAREN), "EXPRTOKEN_CLOSE_PAREN"); 886 fTokenNames.put(new Integer (EXPRTOKEN_OPEN_BRACKET), "EXPRTOKEN_OPEN_BRACKET"); 887 fTokenNames.put(new Integer (EXPRTOKEN_CLOSE_BRACKET), "EXPRTOKEN_CLOSE_BRACKET"); 888 fTokenNames.put(new Integer (EXPRTOKEN_PERIOD), "EXPRTOKEN_PERIOD"); 889 fTokenNames.put(new Integer (EXPRTOKEN_DOUBLE_PERIOD), "EXPRTOKEN_DOUBLE_PERIOD"); 890 fTokenNames.put(new Integer (EXPRTOKEN_ATSIGN), "EXPRTOKEN_ATSIGN"); 891 fTokenNames.put(new Integer (EXPRTOKEN_COMMA), "EXPRTOKEN_COMMA"); 892 fTokenNames.put(new Integer (EXPRTOKEN_DOUBLE_COLON), "EXPRTOKEN_DOUBLE_COLON"); 893 fTokenNames.put(new Integer (EXPRTOKEN_NAMETEST_ANY), "EXPRTOKEN_NAMETEST_ANY"); 894 fTokenNames.put(new Integer (EXPRTOKEN_NAMETEST_NAMESPACE), "EXPRTOKEN_NAMETEST_NAMESPACE"); 895 fTokenNames.put(new Integer (EXPRTOKEN_NAMETEST_QNAME), "EXPRTOKEN_NAMETEST_QNAME"); 896 fTokenNames.put(new Integer (EXPRTOKEN_NODETYPE_COMMENT), "EXPRTOKEN_NODETYPE_COMMENT"); 897 fTokenNames.put(new Integer (EXPRTOKEN_NODETYPE_TEXT), "EXPRTOKEN_NODETYPE_TEXT"); 898 fTokenNames.put(new Integer (EXPRTOKEN_NODETYPE_PI), "EXPRTOKEN_NODETYPE_PI"); 899 fTokenNames.put(new Integer (EXPRTOKEN_NODETYPE_NODE), "EXPRTOKEN_NODETYPE_NODE"); 900 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_AND), "EXPRTOKEN_OPERATOR_AND"); 901 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_OR), "EXPRTOKEN_OPERATOR_OR"); 902 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_MOD), "EXPRTOKEN_OPERATOR_MOD"); 903 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_DIV), "EXPRTOKEN_OPERATOR_DIV"); 904 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_MULT), "EXPRTOKEN_OPERATOR_MULT"); 905 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_SLASH), "EXPRTOKEN_OPERATOR_SLASH"); 906 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_DOUBLE_SLASH), "EXPRTOKEN_OPERATOR_DOUBLE_SLASH"); 907 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_UNION), "EXPRTOKEN_OPERATOR_UNION"); 908 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_PLUS), "EXPRTOKEN_OPERATOR_PLUS"); 909 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_MINUS), "EXPRTOKEN_OPERATOR_MINUS"); 910 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_EQUAL), "EXPRTOKEN_OPERATOR_EQUAL"); 911 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_NOT_EQUAL), "EXPRTOKEN_OPERATOR_NOT_EQUAL"); 912 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_LESS), "EXPRTOKEN_OPERATOR_LESS"); 913 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_LESS_EQUAL), "EXPRTOKEN_OPERATOR_LESS_EQUAL"); 914 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_GREATER), "EXPRTOKEN_OPERATOR_GREATER"); 915 fTokenNames.put(new Integer (EXPRTOKEN_OPERATOR_GREATER_EQUAL), "EXPRTOKEN_OPERATOR_GREATER_EQUAL"); 916 fTokenNames.put(new Integer (EXPRTOKEN_FUNCTION_NAME), "EXPRTOKEN_FUNCTION_NAME"); 917 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_ANCESTOR), "EXPRTOKEN_AXISNAME_ANCESTOR"); 918 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF), "EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF"); 919 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_ATTRIBUTE), "EXPRTOKEN_AXISNAME_ATTRIBUTE"); 920 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_CHILD), "EXPRTOKEN_AXISNAME_CHILD"); 921 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_DESCENDANT), "EXPRTOKEN_AXISNAME_DESCENDANT"); 922 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF), "EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF"); 923 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_FOLLOWING), "EXPRTOKEN_AXISNAME_FOLLOWING"); 924 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING), "EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING"); 925 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_NAMESPACE), "EXPRTOKEN_AXISNAME_NAMESPACE"); 926 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_PARENT), "EXPRTOKEN_AXISNAME_PARENT"); 927 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_PRECEDING), "EXPRTOKEN_AXISNAME_PRECEDING"); 928 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_PRECEDING_SIBLING), "EXPRTOKEN_AXISNAME_PRECEDING_SIBLING"); 929 fTokenNames.put(new Integer (EXPRTOKEN_AXISNAME_SELF), "EXPRTOKEN_AXISNAME_SELF"); 930 fTokenNames.put(new Integer (EXPRTOKEN_LITERAL), "EXPRTOKEN_LITERAL"); 931 fTokenNames.put(new Integer (EXPRTOKEN_NUMBER), "EXPRTOKEN_NUMBER"); 932 fTokenNames.put(new Integer (EXPRTOKEN_VARIABLE_REFERENCE), "EXPRTOKEN_VARIABLE_REFERENCE"); 933 } 934 935 939 public String getTokenString(int token) { 946 return (String )fTokenNames.get(new Integer (token)); 947 } 948 949 public void addToken(String tokenStr) { 950 Integer tokenInt = (Integer )fTokenNames.get(tokenStr); 951 if (tokenInt == null) { 952 tokenInt = new Integer (fTokenNames.size()); 953 fTokenNames.put(tokenInt, tokenStr); 954 } 955 addToken(tokenInt.intValue()); 956 } 957 958 public void addToken(int token) { 959 try { 960 fTokens[fTokenCount] = token; 961 } catch (ArrayIndexOutOfBoundsException ex) { 962 int[] oldList = fTokens; 963 fTokens = new int[fTokenCount << 1]; 964 System.arraycopy(oldList, 0, fTokens, 0, fTokenCount); 965 fTokens[fTokenCount] = token; 966 } 967 fTokenCount++; 968 } 969 976 979 public void rewind() { 980 fCurrentTokenIndex=0; 981 } 982 986 public boolean hasMore() { 987 return fCurrentTokenIndex<fTokenCount; 988 } 989 996 public int nextToken() throws XPathException { 997 if( fCurrentTokenIndex==fTokenCount ) 998 throw new XPathException("c-general-xpath"); 999 return fTokens[fCurrentTokenIndex++]; 1000 } 1001 1008 public int peekToken() throws XPathException { 1009 if( fCurrentTokenIndex==fTokenCount ) 1010 throw new XPathException("c-general-xpath"); 1011 return fTokens[fCurrentTokenIndex]; 1012 } 1013 1020 public String nextTokenAsString() throws XPathException { 1021 String s = getTokenString(nextToken()); 1022 if(s==null) throw new XPathException("c-general-xpath"); 1023 return s; 1024 } 1025 1026 public void dumpTokens() { 1027 for (int i = 0; i < fTokenCount; i++) { 1029 switch (fTokens[i]) { 1030 case EXPRTOKEN_OPEN_PAREN: 1031 System.out.print("<OPEN_PAREN/>"); 1032 break; 1033 case EXPRTOKEN_CLOSE_PAREN: 1034 System.out.print("<CLOSE_PAREN/>"); 1035 break; 1036 case EXPRTOKEN_OPEN_BRACKET: 1037 System.out.print("<OPEN_BRACKET/>"); 1038 break; 1039 case EXPRTOKEN_CLOSE_BRACKET: 1040 System.out.print("<CLOSE_BRACKET/>"); 1041 break; 1042 case EXPRTOKEN_PERIOD: 1043 System.out.print("<PERIOD/>"); 1044 break; 1045 case EXPRTOKEN_DOUBLE_PERIOD: 1046 System.out.print("<DOUBLE_PERIOD/>"); 1047 break; 1048 case EXPRTOKEN_ATSIGN: 1049 System.out.print("<ATSIGN/>"); 1050 break; 1051 case EXPRTOKEN_COMMA: 1052 System.out.print("<COMMA/>"); 1053 break; 1054 case EXPRTOKEN_DOUBLE_COLON: 1055 System.out.print("<DOUBLE_COLON/>"); 1056 break; 1057 case EXPRTOKEN_NAMETEST_ANY: 1058 System.out.print("<NAMETEST_ANY/>"); 1059 break; 1060 case EXPRTOKEN_NAMETEST_NAMESPACE: 1061 System.out.print("<NAMETEST_NAMESPACE"); 1062 System.out.print(" prefix=\"" + getTokenString(fTokens[++i]) + "\""); 1063 System.out.print("/>"); 1064 break; 1065 case EXPRTOKEN_NAMETEST_QNAME: 1066 System.out.print("<NAMETEST_QNAME"); 1067 if (fTokens[++i] != -1) 1068 System.out.print(" prefix=\"" + getTokenString(fTokens[i]) + "\""); 1069 System.out.print(" localpart=\"" + getTokenString(fTokens[++i]) + "\""); 1070 System.out.print("/>"); 1071 break; 1072 case EXPRTOKEN_NODETYPE_COMMENT: 1073 System.out.print("<NODETYPE_COMMENT/>"); 1074 break; 1075 case EXPRTOKEN_NODETYPE_TEXT: 1076 System.out.print("<NODETYPE_TEXT/>"); 1077 break; 1078 case EXPRTOKEN_NODETYPE_PI: 1079 System.out.print("<NODETYPE_PI/>"); 1080 break; 1081 case EXPRTOKEN_NODETYPE_NODE: 1082 System.out.print("<NODETYPE_NODE/>"); 1083 break; 1084 case EXPRTOKEN_OPERATOR_AND: 1085 System.out.print("<OPERATOR_AND/>"); 1086 break; 1087 case EXPRTOKEN_OPERATOR_OR: 1088 System.out.print("<OPERATOR_OR/>"); 1089 break; 1090 case EXPRTOKEN_OPERATOR_MOD: 1091 System.out.print("<OPERATOR_MOD/>"); 1092 break; 1093 case EXPRTOKEN_OPERATOR_DIV: 1094 System.out.print("<OPERATOR_DIV/>"); 1095 break; 1096 case EXPRTOKEN_OPERATOR_MULT: 1097 System.out.print("<OPERATOR_MULT/>"); 1098 break; 1099 case EXPRTOKEN_OPERATOR_SLASH: 1100 System.out.print("<OPERATOR_SLASH/>"); 1101 if (i + 1 < fTokenCount) { 1102 System.out.println(); 1103 System.out.print(" "); 1104 } 1105 break; 1106 case EXPRTOKEN_OPERATOR_DOUBLE_SLASH: 1107 System.out.print("<OPERATOR_DOUBLE_SLASH/>"); 1108 break; 1109 case EXPRTOKEN_OPERATOR_UNION: 1110 System.out.print("<OPERATOR_UNION/>"); 1111 break; 1112 case EXPRTOKEN_OPERATOR_PLUS: 1113 System.out.print("<OPERATOR_PLUS/>"); 1114 break; 1115 case EXPRTOKEN_OPERATOR_MINUS: 1116 System.out.print("<OPERATOR_MINUS/>"); 1117 break; 1118 case EXPRTOKEN_OPERATOR_EQUAL: 1119 System.out.print("<OPERATOR_EQUAL/>"); 1120 break; 1121 case EXPRTOKEN_OPERATOR_NOT_EQUAL: 1122 System.out.print("<OPERATOR_NOT_EQUAL/>"); 1123 break; 1124 case EXPRTOKEN_OPERATOR_LESS: 1125 System.out.print("<OPERATOR_LESS/>"); 1126 break; 1127 case EXPRTOKEN_OPERATOR_LESS_EQUAL: 1128 System.out.print("<OPERATOR_LESS_EQUAL/>"); 1129 break; 1130 case EXPRTOKEN_OPERATOR_GREATER: 1131 System.out.print("<OPERATOR_GREATER/>"); 1132 break; 1133 case EXPRTOKEN_OPERATOR_GREATER_EQUAL: 1134 System.out.print("<OPERATOR_GREATER_EQUAL/>"); 1135 break; 1136 case EXPRTOKEN_FUNCTION_NAME: 1137 System.out.print("<FUNCTION_NAME"); 1138 if (fTokens[++i] != -1) 1139 System.out.print(" prefix=\"" + getTokenString(fTokens[i]) + "\""); 1140 System.out.print(" localpart=\"" + getTokenString(fTokens[++i]) + "\""); 1141 System.out.print("/>"); 1142 break; 1143 case EXPRTOKEN_AXISNAME_ANCESTOR: 1144 System.out.print("<AXISNAME_ANCESTOR/>"); 1145 break; 1146 case EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF: 1147 System.out.print("<AXISNAME_ANCESTOR_OR_SELF/>"); 1148 break; 1149 case EXPRTOKEN_AXISNAME_ATTRIBUTE: 1150 System.out.print("<AXISNAME_ATTRIBUTE/>"); 1151 break; 1152 case EXPRTOKEN_AXISNAME_CHILD: 1153 System.out.print("<AXISNAME_CHILD/>"); 1154 break; 1155 case EXPRTOKEN_AXISNAME_DESCENDANT: 1156 System.out.print("<AXISNAME_DESCENDANT/>"); 1157 break; 1158 case EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF: 1159 System.out.print("<AXISNAME_DESCENDANT_OR_SELF/>"); 1160 break; 1161 case EXPRTOKEN_AXISNAME_FOLLOWING: 1162 System.out.print("<AXISNAME_FOLLOWING/>"); 1163 break; 1164 case EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING: 1165 System.out.print("<AXISNAME_FOLLOWING_SIBLING/>"); 1166 break; 1167 case EXPRTOKEN_AXISNAME_NAMESPACE: 1168 System.out.print("<AXISNAME_NAMESPACE/>"); 1169 break; 1170 case EXPRTOKEN_AXISNAME_PARENT: 1171 System.out.print("<AXISNAME_PARENT/>"); 1172 break; 1173 case EXPRTOKEN_AXISNAME_PRECEDING: 1174 System.out.print("<AXISNAME_PRECEDING/>"); 1175 break; 1176 case EXPRTOKEN_AXISNAME_PRECEDING_SIBLING: 1177 System.out.print("<AXISNAME_PRECEDING_SIBLING/>"); 1178 break; 1179 case EXPRTOKEN_AXISNAME_SELF: 1180 System.out.print("<AXISNAME_SELF/>"); 1181 break; 1182 case EXPRTOKEN_LITERAL: 1183 System.out.print("<LITERAL"); 1184 System.out.print(" value=\"" + getTokenString(fTokens[++i]) + "\""); 1185 System.out.print("/>"); 1186 break; 1187 case EXPRTOKEN_NUMBER: 1188 System.out.print("<NUMBER"); 1189 System.out.print(" whole=\"" + getTokenString(fTokens[++i]) + "\""); 1190 System.out.print(" part=\"" + getTokenString(fTokens[++i]) + "\""); 1191 System.out.print("/>"); 1192 break; 1193 case EXPRTOKEN_VARIABLE_REFERENCE: 1194 System.out.print("<VARIABLE_REFERENCE"); 1195 if (fTokens[++i] != -1) 1196 System.out.print(" prefix=\"" + getTokenString(fTokens[i]) + "\""); 1197 System.out.print(" localpart=\"" + getTokenString(fTokens[++i]) + "\""); 1198 System.out.print("/>"); 1199 break; 1200 default: 1201 System.out.println("<???/>"); 1202 } 1203 } 1204 System.out.println(); 1205 } 1207 1208 } 1210 1216 private static class Scanner { 1217 1218 1231 private static final byte 1232 CHARTYPE_INVALID = 0, CHARTYPE_OTHER = 1, CHARTYPE_WHITESPACE = 2, CHARTYPE_EXCLAMATION = 3, CHARTYPE_QUOTE = 4, CHARTYPE_DOLLAR = 5, CHARTYPE_OPEN_PAREN = 6, CHARTYPE_CLOSE_PAREN = 7, CHARTYPE_STAR = 8, CHARTYPE_PLUS = 9, CHARTYPE_COMMA = 10, CHARTYPE_MINUS = 11, CHARTYPE_PERIOD = 12, CHARTYPE_SLASH = 13, CHARTYPE_DIGIT = 14, CHARTYPE_COLON = 15, CHARTYPE_LESS = 16, CHARTYPE_EQUAL = 17, CHARTYPE_GREATER = 18, CHARTYPE_ATSIGN = 19, CHARTYPE_LETTER = 20, CHARTYPE_OPEN_BRACKET = 21, CHARTYPE_CLOSE_BRACKET = 22, CHARTYPE_UNDERSCORE = 23, CHARTYPE_UNION = 24, CHARTYPE_NONASCII = 25; 1259 private static final byte[] fASCIICharMap = { 1260 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 2, 0, 0, 1261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1262 2, 3, 4, 1, 5, 1, 1, 4, 6, 7, 8, 9, 10, 11, 12, 13, 1263 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 1, 16, 17, 18, 1, 1264 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1265 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 1, 22, 1, 23, 1266 1, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1267 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 1, 24, 1, 1, 1 1268 }; 1269 1270 1273 1274 1278 1279 private SymbolTable fSymbolTable; 1280 1281 1283 private static final String fAndSymbol = "and".intern(); 1284 private static final String fOrSymbol = "or".intern(); 1285 private static final String fModSymbol = "mod".intern(); 1286 private static final String fDivSymbol = "div".intern(); 1287 1288 private static final String fCommentSymbol = "comment".intern(); 1289 private static final String fTextSymbol = "text".intern(); 1290 private static final String fPISymbol = "processing-instruction".intern(); 1291 private static final String fNodeSymbol = "node".intern(); 1292 1293 private static final String fAncestorSymbol = "ancestor".intern(); 1294 private static final String fAncestorOrSelfSymbol = "ancestor-or-self".intern(); 1295 private static final String fAttributeSymbol = "attribute".intern(); 1296 private static final String fChildSymbol = "child".intern(); 1297 private static final String fDescendantSymbol = "descendant".intern(); 1298 private static final String fDescendantOrSelfSymbol = "descendant-or-self".intern(); 1299 private static final String fFollowingSymbol = "following".intern(); 1300 private static final String fFollowingSiblingSymbol = "following-sibling".intern(); 1301 private static final String fNamespaceSymbol = "namespace".intern(); 1302 private static final String fParentSymbol = "parent".intern(); 1303 private static final String fPrecedingSymbol = "preceding".intern(); 1304 private static final String fPrecedingSiblingSymbol = "preceding-sibling".intern(); 1305 private static final String fSelfSymbol = "self".intern(); 1306 1307 1311 1312 public Scanner(SymbolTable symbolTable) { 1313 1314 fSymbolTable = symbolTable; 1316 1317 } 1319 1322 public boolean scanExpr(SymbolTable symbolTable, 1323 XPath.Tokens tokens, String data, 1324 int currentOffset, int endOffset) 1325 throws XPathException { 1326 1327 int nameOffset; 1328 String nameHandle, prefixHandle; 1329 boolean starIsMultiplyOperator = false; 1330 int ch; 1331 1332 while (true) { 1333 if (currentOffset == endOffset) { 1334 break; 1335 } 1336 ch = data.charAt(currentOffset); 1337 while (ch == ' ' || ch == 0x0A || ch == 0x09 || ch == 0x0D) { 1341 if (++currentOffset == endOffset) { 1342 break; 1343 } 1344 ch = data.charAt(currentOffset); 1345 } 1346 if (currentOffset == endOffset) { 1347 break; 1348 } 1349 byte chartype = (ch >= 0x80) ? CHARTYPE_NONASCII : fASCIICharMap[ch]; 1355 switch (chartype) { 1356 case CHARTYPE_OPEN_PAREN: addToken(tokens, XPath.Tokens.EXPRTOKEN_OPEN_PAREN); 1358 starIsMultiplyOperator = false; 1359 if (++currentOffset == endOffset) { 1360 break; 1361 } 1362 break; 1363 case CHARTYPE_CLOSE_PAREN: addToken(tokens, XPath.Tokens.EXPRTOKEN_CLOSE_PAREN); 1365 starIsMultiplyOperator = true; 1366 if (++currentOffset == endOffset) { 1367 break; 1368 } 1369 break; 1370 case CHARTYPE_OPEN_BRACKET: addToken(tokens, XPath.Tokens.EXPRTOKEN_OPEN_BRACKET); 1372 starIsMultiplyOperator = false; 1373 if (++currentOffset == endOffset) { 1374 break; 1375 } 1376 break; 1377 case CHARTYPE_CLOSE_BRACKET: addToken(tokens, XPath.Tokens.EXPRTOKEN_CLOSE_BRACKET); 1379 starIsMultiplyOperator = true; 1380 if (++currentOffset == endOffset) { 1381 break; 1382 } 1383 break; 1384 case CHARTYPE_PERIOD: if (currentOffset + 1 == endOffset) { 1390 addToken(tokens, XPath.Tokens.EXPRTOKEN_PERIOD); 1391 starIsMultiplyOperator = true; 1392 currentOffset++; 1393 break; 1394 } 1395 ch = data.charAt(currentOffset + 1); 1396 if (ch == '.') { addToken(tokens, XPath.Tokens.EXPRTOKEN_DOUBLE_PERIOD); 1398 starIsMultiplyOperator = true; 1399 currentOffset += 2; 1400 } else if (ch >= '0' && ch <= '9') { 1401 addToken(tokens, XPath.Tokens.EXPRTOKEN_NUMBER); 1402 starIsMultiplyOperator = true; 1403 currentOffset = scanNumber(tokens, data, endOffset, currentOffset); 1404 } else if (ch == '/') { 1405 addToken(tokens, XPath.Tokens.EXPRTOKEN_PERIOD); 1406 starIsMultiplyOperator = true; 1407 currentOffset++; 1408 } else if (ch == '|') { 1409 addToken(tokens, XPath.Tokens.EXPRTOKEN_PERIOD); 1410 starIsMultiplyOperator = true; 1411 currentOffset++; 1412 break; 1413 } else if (ch == ' ' || ch == 0x0A || ch == 0x09 || ch == 0x0D) { 1414 do { 1416 if (++currentOffset == endOffset) { 1417 break; 1418 } 1419 ch = data.charAt(currentOffset); 1420 } while (ch == ' ' || ch == 0x0A || ch == 0x09 || ch == 0x0D); 1421 if (currentOffset == endOffset || ch == '|') { 1422 addToken(tokens, XPath.Tokens.EXPRTOKEN_PERIOD); 1423 starIsMultiplyOperator = true; 1424 break; 1425 } 1426 throw new XPathException ("c-general-xpath"); 1427 } else { throw new XPathException ("c-general-xpath"); 1429 } 1430 if (currentOffset == endOffset) { 1431 break; 1432 } 1433 break; 1434 case CHARTYPE_ATSIGN: addToken(tokens, XPath.Tokens.EXPRTOKEN_ATSIGN); 1436 starIsMultiplyOperator = false; 1437 if (++currentOffset == endOffset) { 1438 break; 1439 } 1440 break; 1441 case CHARTYPE_COMMA: addToken(tokens, XPath.Tokens.EXPRTOKEN_COMMA); 1443 starIsMultiplyOperator = false; 1444 if (++currentOffset == endOffset) { 1445 break; 1446 } 1447 break; 1448 case CHARTYPE_COLON: if (++currentOffset == endOffset) { 1450 return false; } 1453 ch = data.charAt(currentOffset); 1454 if (ch != ':') { 1455 return false; } 1458 addToken(tokens, XPath.Tokens.EXPRTOKEN_DOUBLE_COLON); 1459 starIsMultiplyOperator = false; 1460 if (++currentOffset == endOffset) { 1461 break; 1462 } 1463 break; 1464 case CHARTYPE_SLASH: if (++currentOffset == endOffset) { 1466 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_SLASH); 1467 starIsMultiplyOperator = false; 1468 break; 1469 } 1470 ch = data.charAt(currentOffset); 1471 if (ch == '/') { addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_DOUBLE_SLASH); 1473 starIsMultiplyOperator = false; 1474 if (++currentOffset == endOffset) { 1475 break; 1476 } 1477 } else { 1478 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_SLASH); 1479 starIsMultiplyOperator = false; 1480 } 1481 break; 1482 case CHARTYPE_UNION: addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_UNION); 1484 starIsMultiplyOperator = false; 1485 if (++currentOffset == endOffset) { 1486 break; 1487 } 1488 break; 1489 case CHARTYPE_PLUS: addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_PLUS); 1491 starIsMultiplyOperator = false; 1492 if (++currentOffset == endOffset) { 1493 break; 1494 } 1495 break; 1496 case CHARTYPE_MINUS: addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_MINUS); 1498 starIsMultiplyOperator = false; 1499 if (++currentOffset == endOffset) { 1500 break; 1501 } 1502 break; 1503 case CHARTYPE_EQUAL: addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_EQUAL); 1505 starIsMultiplyOperator = false; 1506 if (++currentOffset == endOffset) { 1507 break; 1508 } 1509 break; 1510 case CHARTYPE_EXCLAMATION: if (++currentOffset == endOffset) { 1512 return false; } 1515 ch = data.charAt(currentOffset); 1516 if (ch != '=') { 1517 return false; } 1520 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_NOT_EQUAL); 1521 starIsMultiplyOperator = false; 1522 if (++currentOffset == endOffset) { 1523 break; 1524 } 1525 break; 1526 case CHARTYPE_LESS: if (++currentOffset == endOffset) { 1528 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_LESS); 1529 starIsMultiplyOperator = false; 1530 break; 1531 } 1532 ch = data.charAt(currentOffset); 1533 if (ch == '=') { addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_LESS_EQUAL); 1535 starIsMultiplyOperator = false; 1536 if (++currentOffset == endOffset) { 1537 break; 1538 } 1539 } else { 1540 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_LESS); 1541 starIsMultiplyOperator = false; 1542 } 1543 break; 1544 case CHARTYPE_GREATER: if (++currentOffset == endOffset) { 1546 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_GREATER); 1547 starIsMultiplyOperator = false; 1548 break; 1549 } 1550 ch = data.charAt(currentOffset); 1551 if (ch == '=') { addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_GREATER_EQUAL); 1553 starIsMultiplyOperator = false; 1554 if (++currentOffset == endOffset) { 1555 break; 1556 } 1557 } else { 1558 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_GREATER); 1559 starIsMultiplyOperator = false; 1560 } 1561 break; 1562 case CHARTYPE_QUOTE: int qchar = ch; 1567 if (++currentOffset == endOffset) { 1568 return false; } 1571 ch = data.charAt(currentOffset); 1572 int litOffset = currentOffset; 1573 while (ch != qchar) { 1574 if (++currentOffset == endOffset) { 1575 return false; } 1578 ch = data.charAt(currentOffset); 1579 } 1580 int litLength = currentOffset - litOffset; 1581 addToken(tokens, XPath.Tokens.EXPRTOKEN_LITERAL); 1582 starIsMultiplyOperator = true; 1583 tokens.addToken(symbolTable.addSymbol(data.substring(litOffset, litOffset + litLength))); 1584 if (++currentOffset == endOffset) { 1585 break; 1586 } 1587 break; 1588 case CHARTYPE_DIGIT: 1593 addToken(tokens, XPath.Tokens.EXPRTOKEN_NUMBER); 1594 starIsMultiplyOperator = true; 1595 currentOffset = scanNumber(tokens, data, endOffset, currentOffset); 1596 break; 1597 case CHARTYPE_DOLLAR: 1601 if (++currentOffset == endOffset) { 1602 return false; } 1605 nameOffset = currentOffset; 1606 currentOffset = scanNCName(data, endOffset, currentOffset); 1607 if (currentOffset == nameOffset) { 1608 return false; } 1611 if (currentOffset < endOffset) { 1612 ch = data.charAt(currentOffset); 1613 } 1614 else { 1615 ch = -1; 1616 } 1617 nameHandle = symbolTable.addSymbol(data.substring(nameOffset, currentOffset)); 1618 if (ch != ':') { 1619 prefixHandle = XMLSymbols.EMPTY_STRING; 1620 } else { 1621 prefixHandle = nameHandle; 1622 if (++currentOffset == endOffset) { 1623 return false; } 1626 nameOffset = currentOffset; 1627 currentOffset = scanNCName(data, endOffset, currentOffset); 1628 if (currentOffset == nameOffset) { 1629 return false; } 1632 if (currentOffset < endOffset) { 1633 ch = data.charAt(currentOffset); 1634 } 1635 else { 1636 ch = -1; 1637 } 1638 nameHandle = symbolTable.addSymbol(data.substring(nameOffset, currentOffset)); 1639 } 1640 addToken(tokens, XPath.Tokens.EXPRTOKEN_VARIABLE_REFERENCE); 1641 starIsMultiplyOperator = true; 1642 tokens.addToken(prefixHandle); 1643 tokens.addToken(nameHandle); 1644 break; 1645 case CHARTYPE_STAR: if (starIsMultiplyOperator) { 1659 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_MULT); 1660 starIsMultiplyOperator = false; 1661 } else { 1662 addToken(tokens, XPath.Tokens.EXPRTOKEN_NAMETEST_ANY); 1663 starIsMultiplyOperator = true; 1664 } 1665 if (++currentOffset == endOffset) { 1666 break; 1667 } 1668 break; 1669 case CHARTYPE_NONASCII: case CHARTYPE_LETTER: 1674 case CHARTYPE_UNDERSCORE: 1675 nameOffset = currentOffset; 1703 currentOffset = scanNCName(data, endOffset, currentOffset); 1704 if (currentOffset == nameOffset) { 1705 return false; } 1708 if (currentOffset < endOffset) { 1709 ch = data.charAt(currentOffset); 1710 } 1711 else { 1712 ch = -1; 1713 } 1714 nameHandle = symbolTable.addSymbol(data.substring(nameOffset, currentOffset)); 1715 boolean isNameTestNCName = false; 1716 boolean isAxisName = false; 1717 prefixHandle = XMLSymbols.EMPTY_STRING; 1718 if (ch == ':') { 1719 if (++currentOffset == endOffset) { 1720 return false; } 1723 ch = data.charAt(currentOffset); 1724 if (ch == '*') { 1725 if (++currentOffset < endOffset) { 1726 ch = data.charAt(currentOffset); 1727 } 1728 isNameTestNCName = true; 1729 } else if (ch == ':') { 1730 if (++currentOffset < endOffset) { 1731 ch = data.charAt(currentOffset); 1732 } 1733 isAxisName = true; 1734 } else { 1735 prefixHandle = nameHandle; 1736 nameOffset = currentOffset; 1737 currentOffset = scanNCName(data, endOffset, currentOffset); 1738 if (currentOffset == nameOffset) { 1739 return false; } 1742 if (currentOffset < endOffset) { 1743 ch = data.charAt(currentOffset); 1744 } 1745 else { 1746 ch = -1; 1747 } 1748 nameHandle = symbolTable.addSymbol(data.substring(nameOffset, currentOffset)); 1749 } 1750 } 1751 while (ch == ' ' || ch == 0x0A || ch == 0x09 || ch == 0x0D) { 1755 if (++currentOffset == endOffset) { 1756 break; 1757 } 1758 ch = data.charAt(currentOffset); 1759 } 1760 if (starIsMultiplyOperator) { 1765 if (nameHandle == fAndSymbol) { 1766 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_AND); 1767 starIsMultiplyOperator = false; 1768 } else if (nameHandle == fOrSymbol) { 1769 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_OR); 1770 starIsMultiplyOperator = false; 1771 } else if (nameHandle == fModSymbol) { 1772 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_MOD); 1773 starIsMultiplyOperator = false; 1774 } else if (nameHandle == fDivSymbol) { 1775 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPERATOR_DIV); 1776 starIsMultiplyOperator = false; 1777 } else { 1778 return false; } 1781 if (isNameTestNCName) { 1782 return false; } else if (isAxisName) { 1785 return false; } 1788 break; 1789 } 1790 if (ch == '(' && !isNameTestNCName && !isAxisName) { 1795 if (nameHandle == fCommentSymbol) { 1796 addToken(tokens, XPath.Tokens.EXPRTOKEN_NODETYPE_COMMENT); 1797 } else if (nameHandle == fTextSymbol) { 1798 addToken(tokens, XPath.Tokens.EXPRTOKEN_NODETYPE_TEXT); 1799 } else if (nameHandle == fPISymbol) { 1800 addToken(tokens, XPath.Tokens.EXPRTOKEN_NODETYPE_PI); 1801 } else if (nameHandle == fNodeSymbol) { 1802 addToken(tokens, XPath.Tokens.EXPRTOKEN_NODETYPE_NODE); 1803 } else { 1804 addToken(tokens, XPath.Tokens.EXPRTOKEN_FUNCTION_NAME); 1805 tokens.addToken(prefixHandle); 1806 tokens.addToken(nameHandle); 1807 } 1808 addToken(tokens, XPath.Tokens.EXPRTOKEN_OPEN_PAREN); 1809 starIsMultiplyOperator = false; 1810 if (++currentOffset == endOffset) { 1811 break; 1812 } 1813 break; 1814 } 1815 if (isAxisName || 1820 (ch == ':' && currentOffset + 1 < endOffset && 1821 data.charAt(currentOffset + 1) == ':')) { 1822 if (nameHandle == fAncestorSymbol) { 1823 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_ANCESTOR); 1824 } else if (nameHandle == fAncestorOrSelfSymbol) { 1825 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF); 1826 } else if (nameHandle == fAttributeSymbol) { 1827 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_ATTRIBUTE); 1828 } else if (nameHandle == fChildSymbol) { 1829 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_CHILD); 1830 } else if (nameHandle == fDescendantSymbol) { 1831 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_DESCENDANT); 1832 } else if (nameHandle == fDescendantOrSelfSymbol) { 1833 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF); 1834 } else if (nameHandle == fFollowingSymbol) { 1835 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_FOLLOWING); 1836 } else if (nameHandle == fFollowingSiblingSymbol) { 1837 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING); 1838 } else if (nameHandle == fNamespaceSymbol) { 1839 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_NAMESPACE); 1840 } else if (nameHandle == fParentSymbol) { 1841 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_PARENT); 1842 } else if (nameHandle == fPrecedingSymbol) { 1843 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_PRECEDING); 1844 } else if (nameHandle == fPrecedingSiblingSymbol) { 1845 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_PRECEDING_SIBLING); 1846 } else if (nameHandle == fSelfSymbol) { 1847 addToken(tokens, XPath.Tokens.EXPRTOKEN_AXISNAME_SELF); 1848 } else { 1849 return false; } 1852 if (isNameTestNCName) { 1853 return false; } 1856 addToken(tokens, XPath.Tokens.EXPRTOKEN_DOUBLE_COLON); 1857 starIsMultiplyOperator = false; 1858 if (!isAxisName) { 1859 currentOffset++; 1860 if (++currentOffset == endOffset) { 1861 break; 1862 } 1863 } 1864 break; 1865 } 1866 if (isNameTestNCName) { 1871 addToken(tokens, XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE); 1872 starIsMultiplyOperator = true; 1873 tokens.addToken(nameHandle); 1874 } else { 1875 addToken(tokens, XPath.Tokens.EXPRTOKEN_NAMETEST_QNAME); 1876 starIsMultiplyOperator = true; 1877 tokens.addToken(prefixHandle); 1878 tokens.addToken(nameHandle); 1879 } 1880 break; 1881 } 1882 } 1883 if (XPath.Tokens.DUMP_TOKENS) { 1884 tokens.dumpTokens(); 1885 } 1886 return true; 1887 } 1888 int scanNCName(String data, int endOffset, int currentOffset) { 1893 int ch = data.charAt(currentOffset); 1894 if (ch >= 0x80) { 1895 if (!XMLChar.isNameStart(ch)) 1896 1900 { 1901 return currentOffset; 1902 } 1903 } 1904 else { 1905 byte chartype = fASCIICharMap[ch]; 1906 if (chartype != CHARTYPE_LETTER && chartype != CHARTYPE_UNDERSCORE) { 1907 return currentOffset; 1908 } 1909 } 1910 while (++currentOffset < endOffset) { 1911 ch = data.charAt(currentOffset); 1912 if (ch >= 0x80) { 1913 if (!XMLChar.isName(ch)) 1914 1918 { 1919 break; 1920 } 1921 } 1922 else { 1923 byte chartype = fASCIICharMap[ch]; 1924 if (chartype != CHARTYPE_LETTER && chartype != CHARTYPE_DIGIT && 1925 chartype != CHARTYPE_PERIOD && chartype != CHARTYPE_MINUS && 1926 chartype != CHARTYPE_UNDERSCORE) 1927 { 1928 break; 1929 } 1930 } 1931 } 1932 return currentOffset; 1933 } 1934 private int scanNumber(XPath.Tokens tokens, String data, int endOffset, int currentOffset) { 1939 int ch = data.charAt(currentOffset); 1940 int whole = 0; 1941 int part = 0; 1942 while (ch >= '0' && ch <= '9') { 1943 whole = (whole * 10) + (ch - '0'); 1944 if (++currentOffset == endOffset) { 1945 break; 1946 } 1947 ch = data.charAt(currentOffset); 1948 } 1949 if (ch == '.') { 1950 if (++currentOffset < endOffset) { 1951 int start = currentOffset; 1952 ch = data.charAt(currentOffset); 1953 while (ch >= '0' && ch <= '9') { 1954 part = (part * 10) + (ch - '0'); 1955 if (++currentOffset == endOffset) { 1956 break; 1957 } 1958 ch = data.charAt(currentOffset); 1959 } 1960 if (part != 0) { 1961 1964 throw new RuntimeException ("find a solution!"); 1965 1967 } 1968 } 1969 } 1970 tokens.addToken(whole); 1971 tokens.addToken(part); 1972 return currentOffset; 1973 } 1974 1975 1979 1987 protected void addToken(XPath.Tokens tokens, int token) 1988 throws XPathException { 1989 tokens.addToken(token); 1990 } 1992 } 1994 1998 1999 public static void main(String [] argv) throws Exception { 2000 2001 for (int i = 0; i < argv.length; i++) { 2002 final String expression = argv[i]; 2003 System.out.println("# XPath expression: \""+expression+'"'); 2004 try { 2005 SymbolTable symbolTable = new SymbolTable(); 2006 XPath xpath = new XPath(expression, symbolTable, null); 2007 System.out.println("expanded xpath: \""+xpath.toString()+'"'); 2008 } 2009 catch (XPathException e) { 2010 System.out.println("error: "+e.getMessage()); 2011 } 2012 } 2013 2014 } 2016} | Popular Tags |