1 16 19 package org.apache.xpath.compiler; 20 21 import javax.xml.transform.ErrorListener ; 22 import javax.xml.transform.SourceLocator ; 23 import javax.xml.transform.TransformerException ; 24 25 import org.apache.xalan.res.XSLMessages; 26 import org.apache.xml.dtm.Axis; 27 import org.apache.xml.dtm.DTMFilter; 28 import org.apache.xml.dtm.DTMIterator; 29 import org.apache.xml.utils.PrefixResolver; 30 import org.apache.xml.utils.QName; 31 import org.apache.xml.utils.SAXSourceLocator; 32 import org.apache.xpath.Expression; 33 import org.apache.xpath.axes.UnionPathIterator; 34 import org.apache.xpath.axes.WalkerFactory; 35 import org.apache.xpath.functions.FuncExtFunction; 36 import org.apache.xpath.functions.Function; 37 import org.apache.xpath.functions.WrongNumberArgsException; 38 import org.apache.xpath.objects.XNumber; 39 import org.apache.xpath.objects.XString; 40 import org.apache.xpath.operations.And; 41 import org.apache.xpath.operations.Div; 42 import org.apache.xpath.operations.Equals; 43 import org.apache.xpath.operations.Gt; 44 import org.apache.xpath.operations.Gte; 45 import org.apache.xpath.operations.Lt; 46 import org.apache.xpath.operations.Lte; 47 import org.apache.xpath.operations.Minus; 48 import org.apache.xpath.operations.Mod; 49 import org.apache.xpath.operations.Mult; 50 import org.apache.xpath.operations.Neg; 51 import org.apache.xpath.operations.NotEquals; 52 import org.apache.xpath.operations.Operation; 53 import org.apache.xpath.operations.Or; 54 import org.apache.xpath.operations.Plus; 55 import org.apache.xpath.operations.UnaryOperation; 56 import org.apache.xpath.operations.Variable; 57 import org.apache.xpath.patterns.FunctionPattern; 58 import org.apache.xpath.patterns.NodeTest; 59 import org.apache.xpath.patterns.StepPattern; 60 import org.apache.xpath.patterns.UnionPattern; 61 import org.apache.xpath.res.XPATHErrorResources; 62 63 70 public class Compiler extends OpMap 71 { 72 73 83 public Compiler(ErrorListener errorHandler, SourceLocator locator) 84 { 85 m_errorHandler = errorHandler; 86 m_locator = locator; 87 } 88 89 93 public Compiler() 94 { 95 m_errorHandler = null; 96 m_locator = null; 97 } 98 99 111 public Expression compile(int opPos) throws TransformerException 112 { 113 114 int op = getOp(opPos); 115 116 Expression expr = null; 117 switch (op) 119 { 120 case OpCodes.OP_XPATH : 121 expr = compile(opPos + 2); break; 122 case OpCodes.OP_OR : 123 expr = or(opPos); break; 124 case OpCodes.OP_AND : 125 expr = and(opPos); break; 126 case OpCodes.OP_NOTEQUALS : 127 expr = notequals(opPos); break; 128 case OpCodes.OP_EQUALS : 129 expr = equals(opPos); break; 130 case OpCodes.OP_LTE : 131 expr = lte(opPos); break; 132 case OpCodes.OP_LT : 133 expr = lt(opPos); break; 134 case OpCodes.OP_GTE : 135 expr = gte(opPos); break; 136 case OpCodes.OP_GT : 137 expr = gt(opPos); break; 138 case OpCodes.OP_PLUS : 139 expr = plus(opPos); break; 140 case OpCodes.OP_MINUS : 141 expr = minus(opPos); break; 142 case OpCodes.OP_MULT : 143 expr = mult(opPos); break; 144 case OpCodes.OP_DIV : 145 expr = div(opPos); break; 146 case OpCodes.OP_MOD : 147 expr = mod(opPos); break; 148 case OpCodes.OP_NEG : 151 expr = neg(opPos); break; 152 case OpCodes.OP_STRING : 153 expr = string(opPos); break; 154 case OpCodes.OP_BOOL : 155 expr = bool(opPos); break; 156 case OpCodes.OP_NUMBER : 157 expr = number(opPos); break; 158 case OpCodes.OP_UNION : 159 expr = union(opPos); break; 160 case OpCodes.OP_LITERAL : 161 expr = literal(opPos); break; 162 case OpCodes.OP_VARIABLE : 163 expr = variable(opPos); break; 164 case OpCodes.OP_GROUP : 165 expr = group(opPos); break; 166 case OpCodes.OP_NUMBERLIT : 167 expr = numberlit(opPos); break; 168 case OpCodes.OP_ARGUMENT : 169 expr = arg(opPos); break; 170 case OpCodes.OP_EXTFUNCTION : 171 expr = compileExtension(opPos); break; 172 case OpCodes.OP_FUNCTION : 173 expr = compileFunction(opPos); break; 174 case OpCodes.OP_LOCATIONPATH : 175 expr = locationPath(opPos); break; 176 case OpCodes.OP_PREDICATE : 177 expr = null; break; case OpCodes.OP_MATCHPATTERN : 179 expr = matchPattern(opPos + 2); break; 180 case OpCodes.OP_LOCATIONPATHPATTERN : 181 expr = locationPathPattern(opPos); break; 182 case OpCodes.OP_QUO: 183 error(XPATHErrorResources.ER_UNKNOWN_OPCODE, 184 new Object []{ "quo" }); break; 186 default : 187 error(XPATHErrorResources.ER_UNKNOWN_OPCODE, 188 new Object []{ Integer.toString(getOp(opPos)) }); } 190 193 return expr; 194 } 195 196 206 private Expression compileOperation(Operation operation, int opPos) 207 throws TransformerException 208 { 209 210 int leftPos = getFirstChildPos(opPos); 211 int rightPos = getNextOpPos(leftPos); 212 213 operation.setLeftRight(compile(leftPos), compile(rightPos)); 214 215 return operation; 216 } 217 218 228 private Expression compileUnary(UnaryOperation unary, int opPos) 229 throws TransformerException 230 { 231 232 int rightPos = getFirstChildPos(opPos); 233 234 unary.setRight(compile(rightPos)); 235 236 return unary; 237 } 238 239 248 protected Expression or(int opPos) throws TransformerException 249 { 250 return compileOperation(new Or(), opPos); 251 } 252 253 262 protected Expression and(int opPos) throws TransformerException 263 { 264 return compileOperation(new And(), opPos); 265 } 266 267 276 protected Expression notequals(int opPos) throws TransformerException 277 { 278 return compileOperation(new NotEquals(), opPos); 279 } 280 281 290 protected Expression equals(int opPos) throws TransformerException 291 { 292 return compileOperation(new Equals(), opPos); 293 } 294 295 304 protected Expression lte(int opPos) throws TransformerException 305 { 306 return compileOperation(new Lte(), opPos); 307 } 308 309 318 protected Expression lt(int opPos) throws TransformerException 319 { 320 return compileOperation(new Lt(), opPos); 321 } 322 323 332 protected Expression gte(int opPos) throws TransformerException 333 { 334 return compileOperation(new Gte(), opPos); 335 } 336 337 346 protected Expression gt(int opPos) throws TransformerException 347 { 348 return compileOperation(new Gt(), opPos); 349 } 350 351 360 protected Expression plus(int opPos) throws TransformerException 361 { 362 return compileOperation(new Plus(), opPos); 363 } 364 365 374 protected Expression minus(int opPos) throws TransformerException 375 { 376 return compileOperation(new Minus(), opPos); 377 } 378 379 388 protected Expression mult(int opPos) throws TransformerException 389 { 390 return compileOperation(new Mult(), opPos); 391 } 392 393 402 protected Expression div(int opPos) throws TransformerException 403 { 404 return compileOperation(new Div(), opPos); 405 } 406 407 416 protected Expression mod(int opPos) throws TransformerException 417 { 418 return compileOperation(new Mod(), opPos); 419 } 420 421 430 435 444 protected Expression neg(int opPos) throws TransformerException 445 { 446 return compileUnary(new Neg(), opPos); 447 } 448 449 458 protected Expression string(int opPos) throws TransformerException 459 { 460 return compileUnary(new org.apache.xpath.operations.String(), opPos); 461 } 462 463 472 protected Expression bool(int opPos) throws TransformerException 473 { 474 return compileUnary(new org.apache.xpath.operations.Bool(), opPos); 475 } 476 477 486 protected Expression number(int opPos) throws TransformerException 487 { 488 return compileUnary(new org.apache.xpath.operations.Number(), opPos); 489 } 490 491 500 protected Expression literal(int opPos) 501 { 502 503 opPos = getFirstChildPos(opPos); 504 505 return (XString) getTokenQueue().elementAt(getOp(opPos)); 506 } 507 508 517 protected Expression numberlit(int opPos) 518 { 519 520 opPos = getFirstChildPos(opPos); 521 522 return (XNumber) getTokenQueue().elementAt(getOp(opPos)); 523 } 524 525 534 protected Expression variable(int opPos) throws TransformerException 535 { 536 537 Variable var = new Variable(); 538 539 opPos = getFirstChildPos(opPos); 540 541 int nsPos = getOp(opPos); 542 java.lang.String namespace 543 = (OpCodes.EMPTY == nsPos) ? null 544 : (java.lang.String ) getTokenQueue().elementAt(nsPos); 545 java.lang.String localname 546 = (java.lang.String ) getTokenQueue().elementAt(getOp(opPos+1)); 547 QName qname = new QName(namespace, localname); 548 549 var.setQName(qname); 550 551 return var; 552 } 553 554 563 protected Expression group(int opPos) throws TransformerException 564 { 565 566 return compile(opPos + 2); 568 } 569 570 579 protected Expression arg(int opPos) throws TransformerException 580 { 581 582 return compile(opPos + 2); 584 } 585 586 596 protected Expression union(int opPos) throws TransformerException 597 { 598 locPathDepth++; 599 try 600 { 601 return UnionPathIterator.createUnionIterator(this, opPos); 602 } 603 finally 604 { 605 locPathDepth--; 606 } 607 } 608 609 private int locPathDepth = -1; 610 611 615 public int getLocationPathDepth() 616 { 617 return locPathDepth; 618 } 619 620 630 public Expression locationPath(int opPos) throws TransformerException 631 { 632 locPathDepth++; 633 try 634 { 635 DTMIterator iter = WalkerFactory.newDTMIterator(this, opPos, (locPathDepth == 0)); 636 return (Expression)iter; } 638 finally 639 { 640 locPathDepth--; 641 } 642 } 643 644 653 public Expression predicate(int opPos) throws TransformerException 654 { 655 return compile(opPos + 2); 656 } 657 658 667 protected Expression matchPattern(int opPos) throws TransformerException 668 { 669 locPathDepth++; 670 try 671 { 672 int nextOpPos = opPos; 674 int i; 675 676 for (i = 0; getOp(nextOpPos) == OpCodes.OP_LOCATIONPATHPATTERN; i++) 677 { 678 nextOpPos = getNextOpPos(nextOpPos); 679 } 680 681 if (i == 1) 682 return compile(opPos); 683 684 UnionPattern up = new UnionPattern(); 685 StepPattern[] patterns = new StepPattern[i]; 686 687 for (i = 0; getOp(opPos) == OpCodes.OP_LOCATIONPATHPATTERN; i++) 688 { 689 nextOpPos = getNextOpPos(opPos); 690 patterns[i] = (StepPattern) compile(opPos); 691 opPos = nextOpPos; 692 } 693 694 up.setPatterns(patterns); 695 696 return up; 697 } 698 finally 699 { 700 locPathDepth--; 701 } 702 } 703 704 713 public Expression locationPathPattern(int opPos) 714 throws TransformerException 715 { 716 717 opPos = getFirstChildPos(opPos); 718 719 return stepPattern(opPos, 0, null); 720 } 721 722 731 public int getWhatToShow(int opPos) 732 { 733 734 int axesType = getOp(opPos); 735 int testType = getOp(opPos + 3); 736 737 switch (testType) 739 { 740 case OpCodes.NODETYPE_COMMENT : 741 return DTMFilter.SHOW_COMMENT; 742 case OpCodes.NODETYPE_TEXT : 743 return DTMFilter.SHOW_TEXT | DTMFilter.SHOW_CDATA_SECTION ; 745 case OpCodes.NODETYPE_PI : 746 return DTMFilter.SHOW_PROCESSING_INSTRUCTION; 747 case OpCodes.NODETYPE_NODE : 748 switch (axesType) 750 { 751 case OpCodes.FROM_NAMESPACE: 752 return DTMFilter.SHOW_NAMESPACE; 753 case OpCodes.FROM_ATTRIBUTES : 754 case OpCodes.MATCH_ATTRIBUTE : 755 return DTMFilter.SHOW_ATTRIBUTE; 756 case OpCodes.FROM_SELF: 757 case OpCodes.FROM_ANCESTORS_OR_SELF: 758 case OpCodes.FROM_DESCENDANTS_OR_SELF: 759 return DTMFilter.SHOW_ALL; 760 default: 761 if (getOp(0) == OpCodes.OP_MATCHPATTERN) 762 return ~DTMFilter.SHOW_ATTRIBUTE 763 & ~DTMFilter.SHOW_DOCUMENT 764 & ~DTMFilter.SHOW_DOCUMENT_FRAGMENT; 765 else 766 return ~DTMFilter.SHOW_ATTRIBUTE; 767 } 768 case OpCodes.NODETYPE_ROOT : 769 return DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT; 770 case OpCodes.NODETYPE_FUNCTEST : 771 return NodeTest.SHOW_BYFUNCTION; 772 case OpCodes.NODENAME : 773 switch (axesType) 774 { 775 case OpCodes.FROM_NAMESPACE : 776 return DTMFilter.SHOW_NAMESPACE; 777 case OpCodes.FROM_ATTRIBUTES : 778 case OpCodes.MATCH_ATTRIBUTE : 779 return DTMFilter.SHOW_ATTRIBUTE; 780 781 case OpCodes.MATCH_ANY_ANCESTOR : 783 case OpCodes.MATCH_IMMEDIATE_ANCESTOR : 784 return DTMFilter.SHOW_ELEMENT; 785 786 default : 788 return DTMFilter.SHOW_ELEMENT; 789 } 790 default : 791 return DTMFilter.SHOW_ALL; 793 } 794 } 795 796 private static final boolean DEBUG = false; 797 798 810 protected StepPattern stepPattern( 811 int opPos, int stepCount, StepPattern ancestorPattern) 812 throws TransformerException 813 { 814 815 int startOpPos = opPos; 816 int stepType = getOp(opPos); 817 818 if (OpCodes.ENDOP == stepType) 819 { 820 return null; 821 } 822 823 boolean addMagicSelf = true; 824 825 int endStep = getNextOpPos(opPos); 826 827 StepPattern pattern; 829 830 int argLen; 832 833 switch (stepType) 834 { 835 case OpCodes.OP_FUNCTION : 836 if(DEBUG) 837 System.out.println("MATCH_FUNCTION: "+m_currentPattern); 838 addMagicSelf = false; 839 argLen = getOp(opPos + OpMap.MAPINDEX_LENGTH); 840 pattern = new FunctionPattern(compileFunction(opPos), Axis.PARENT, Axis.CHILD); 841 break; 842 case OpCodes.FROM_ROOT : 843 if(DEBUG) 844 System.out.println("FROM_ROOT, "+m_currentPattern); 845 addMagicSelf = false; 846 argLen = getArgLengthOfStep(opPos); 847 opPos = getFirstChildPosOfStep(opPos); 848 pattern = new StepPattern(DTMFilter.SHOW_DOCUMENT | 849 DTMFilter.SHOW_DOCUMENT_FRAGMENT, 850 Axis.PARENT, Axis.CHILD); 851 break; 852 case OpCodes.MATCH_ATTRIBUTE : 853 if(DEBUG) 854 System.out.println("MATCH_ATTRIBUTE: "+getStepLocalName(startOpPos)+", "+m_currentPattern); 855 argLen = getArgLengthOfStep(opPos); 856 opPos = getFirstChildPosOfStep(opPos); 857 pattern = new StepPattern(DTMFilter.SHOW_ATTRIBUTE, 858 getStepNS(startOpPos), 859 getStepLocalName(startOpPos), 860 Axis.PARENT, Axis.ATTRIBUTE); 861 break; 862 case OpCodes.MATCH_ANY_ANCESTOR : 863 if(DEBUG) 864 System.out.println("MATCH_ANY_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern); 865 argLen = getArgLengthOfStep(opPos); 866 opPos = getFirstChildPosOfStep(opPos); 867 int what = getWhatToShow(startOpPos); 868 if(0x00000500 == what) 870 addMagicSelf = false; 871 pattern = new StepPattern(getWhatToShow(startOpPos), 872 getStepNS(startOpPos), 873 getStepLocalName(startOpPos), 874 Axis.ANCESTOR, Axis.CHILD); 875 break; 876 case OpCodes.MATCH_IMMEDIATE_ANCESTOR : 877 if(DEBUG) 878 System.out.println("MATCH_IMMEDIATE_ANCESTOR: "+getStepLocalName(startOpPos)+", "+m_currentPattern); 879 argLen = getArgLengthOfStep(opPos); 880 opPos = getFirstChildPosOfStep(opPos); 881 pattern = new StepPattern(getWhatToShow(startOpPos), 882 getStepNS(startOpPos), 883 getStepLocalName(startOpPos), 884 Axis.PARENT, Axis.CHILD); 885 break; 886 default : 887 error(XPATHErrorResources.ER_UNKNOWN_MATCH_OPERATION, null); 889 return null; 890 } 891 892 pattern.setPredicates(getCompiledPredicates(opPos + argLen)); 893 if(null == ancestorPattern) 894 { 895 914 } 915 else 916 { 917 pattern.setRelativePathPattern(ancestorPattern); 919 } 920 921 StepPattern relativePathPattern = stepPattern(endStep, stepCount + 1, 922 pattern); 923 924 return (null != relativePathPattern) ? relativePathPattern : pattern; 925 } 926 927 936 public Expression[] getCompiledPredicates(int opPos) 937 throws TransformerException 938 { 939 940 int count = countPredicates(opPos); 941 942 if (count > 0) 943 { 944 Expression[] predicates = new Expression[count]; 945 946 compilePredicates(opPos, predicates); 947 948 return predicates; 949 } 950 951 return null; 952 } 953 954 963 public int countPredicates(int opPos) throws TransformerException 964 { 965 966 int count = 0; 967 968 while (OpCodes.OP_PREDICATE == getOp(opPos)) 969 { 970 count++; 971 972 opPos = getNextOpPos(opPos); 973 } 974 975 return count; 976 } 977 978 987 private void compilePredicates(int opPos, Expression[] predicates) 988 throws TransformerException 989 { 990 991 for (int i = 0; OpCodes.OP_PREDICATE == getOp(opPos); i++) 992 { 993 predicates[i] = predicate(opPos); 994 opPos = getNextOpPos(opPos); 995 } 996 } 997 998 1007 Expression compileFunction(int opPos) throws TransformerException 1008 { 1009 1010 int endFunc = opPos + getOp(opPos + 1) - 1; 1011 1012 opPos = getFirstChildPos(opPos); 1013 1014 int funcID = getOp(opPos); 1015 1016 opPos++; 1017 1018 if (-1 != funcID) 1019 { 1020 Function func = FunctionTable.getFunction(funcID); 1021 1022 func.postCompileStep(this); 1023 1024 try 1025 { 1026 int i = 0; 1027 1028 for (int p = opPos; p < endFunc; p = getNextOpPos(p), i++) 1029 { 1030 1031 func.setArg(compile(p), i); 1034 } 1035 1036 func.checkNumberArgs(i); 1037 } 1038 catch (WrongNumberArgsException wnae) 1039 { 1040 java.lang.String name = FunctionTable.m_functions[funcID].getName(); 1041 1042 m_errorHandler.fatalError( new TransformerException ( 1043 XSLMessages.createXPATHMessage(XPATHErrorResources.ER_ONLY_ALLOWS, 1044 new Object []{name, wnae.getMessage()}), m_locator)); 1045 } 1047 1048 return func; 1049 } 1050 else 1051 { 1052 error(XPATHErrorResources.ER_FUNCTION_TOKEN_NOT_FOUND, null); 1054 return null; 1055 } 1056 } 1057 1058 private static long s_nextMethodId = 0; 1060 1061 1064 synchronized private long getNextMethodId() 1065 { 1066 if (s_nextMethodId == Long.MAX_VALUE) 1067 s_nextMethodId = 0; 1068 1069 return s_nextMethodId++; 1070 } 1071 1072 1081 private Expression compileExtension(int opPos) 1082 throws TransformerException 1083 { 1084 1085 int endExtFunc = opPos + getOp(opPos + 1) - 1; 1086 1087 opPos = getFirstChildPos(opPos); 1088 1089 java.lang.String ns = (java.lang.String ) getTokenQueue().elementAt(getOp(opPos)); 1090 1091 opPos++; 1092 1093 java.lang.String funcName = 1094 (java.lang.String ) getTokenQueue().elementAt(getOp(opPos)); 1095 1096 opPos++; 1097 1098 1102 Function extension = new FuncExtFunction(ns, funcName, String.valueOf(getNextMethodId())); 1103 1104 try 1105 { 1106 int i = 0; 1107 1108 while (opPos < endExtFunc) 1109 { 1110 int nextOpPos = getNextOpPos(opPos); 1111 1112 extension.setArg(this.compile(opPos), i); 1113 1114 opPos = nextOpPos; 1115 1116 i++; 1117 } 1118 } 1119 catch (WrongNumberArgsException wnae) 1120 { 1121 ; } 1123 1124 return extension; 1125 } 1126 1127 1139 public void warn(String msg, Object [] args) throws TransformerException 1140 { 1141 1142 java.lang.String fmsg = XSLMessages.createXPATHWarning(msg, args); 1143 1144 if (null != m_errorHandler) 1145 { 1146 m_errorHandler.warning(new TransformerException (fmsg, m_locator)); 1147 } 1148 else 1149 { 1150 System.out.println(fmsg 1151 +"; file "+m_locator.getSystemId() 1152 +"; line "+m_locator.getLineNumber() 1153 +"; column "+m_locator.getColumnNumber()); 1154 } 1155 } 1156 1157 1166 public void assertion(boolean b, java.lang.String msg) 1167 { 1168 1169 if (!b) 1170 { 1171 java.lang.String fMsg = XSLMessages.createXPATHMessage( 1172 XPATHErrorResources.ER_INCORRECT_PROGRAMMER_ASSERTION, 1173 new Object []{ msg }); 1174 1175 throw new RuntimeException (fMsg); 1176 } 1177 } 1178 1179 1192 public void error(String msg, Object [] args) throws TransformerException 1193 { 1194 1195 java.lang.String fmsg = XSLMessages.createXPATHMessage(msg, args); 1196 1197 1198 if (null != m_errorHandler) 1199 { 1200 m_errorHandler.fatalError(new TransformerException (fmsg, m_locator)); 1201 } 1202 else 1203 { 1204 1205 throw new TransformerException (fmsg, (SAXSourceLocator)m_locator); 1210 } 1211 } 1212 1213 1216 private PrefixResolver m_currentPrefixResolver = null; 1217 1218 1223 public PrefixResolver getNamespaceContext() 1224 { 1225 return m_currentPrefixResolver; 1226 } 1227 1228 1233 public void setNamespaceContext(PrefixResolver pr) 1234 { 1235 m_currentPrefixResolver = pr; 1236 } 1237 1238 1240 ErrorListener m_errorHandler; 1241 1242 1243 SourceLocator m_locator; 1244} 1245 | Popular Tags |