walkerfactory.java
来自「java jdk 1.4的源码」· Java 代码 · 共 1,871 行 · 第 1/5 页
JAVA
1,871 行
case OpCodes.FROM_DESCENDANTS : return Axis.DESCENDANT; case OpCodes.FROM_SELF : return Axis.SELF; case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : case OpCodes.OP_VARIABLE : return Axis.FILTEREDLIST; } throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: " //+ stepType); } /** * Get a corresponding BIT_XXX from an axis. * @param axis One of Axis.ANCESTOR, etc. * @return One of BIT_ANCESTOR, etc. */ static public int getAnalysisBitFromAxes(int axis) { switch (axis) // Generate new traverser { case Axis.ANCESTOR : return BIT_ANCESTOR; case Axis.ANCESTORORSELF : return BIT_ANCESTOR_OR_SELF; case Axis.ATTRIBUTE : return BIT_ATTRIBUTE; case Axis.CHILD : return BIT_CHILD; case Axis.DESCENDANT : return BIT_DESCENDANT; case Axis.DESCENDANTORSELF : return BIT_DESCENDANT_OR_SELF; case Axis.FOLLOWING : return BIT_FOLLOWING; case Axis.FOLLOWINGSIBLING : return BIT_FOLLOWING_SIBLING; case Axis.NAMESPACE : case Axis.NAMESPACEDECLS : return BIT_NAMESPACE; case Axis.PARENT : return BIT_PARENT; case Axis.PRECEDING : return BIT_PRECEDING; case Axis.PRECEDINGSIBLING : return BIT_PRECEDING_SIBLING; case Axis.SELF : return BIT_SELF; case Axis.ALLFROMNODE : return BIT_DESCENDANT_OR_SELF; // case Axis.PRECEDINGANDANCESTOR : case Axis.DESCENDANTSFROMROOT : case Axis.ALL : case Axis.DESCENDANTSORSELFFROMROOT : return BIT_ANY_DESCENDANT_FROM_ROOT; case Axis.ROOT : return BIT_ROOT; case Axis.FILTEREDLIST : return BIT_FILTER; default : return BIT_FILTER; } } static boolean functionProximateOrContainsProximate(Compiler compiler, int opPos) { int endFunc = opPos + compiler.getOp(opPos + 1) - 1; opPos = compiler.getFirstChildPos(opPos); int funcID = compiler.getOp(opPos); // System.out.println("funcID: "+funcID); // System.out.println("opPos: "+opPos); // System.out.println("endFunc: "+endFunc); switch(funcID) { case FunctionTable.FUNC_LAST: case FunctionTable.FUNC_POSITION: return true; default: opPos++; int i = 0; for (int p = opPos; p < endFunc; p = compiler.getNextOpPos(p), i++) { int innerExprOpPos = p+2; int argOp = compiler.getOp(innerExprOpPos); boolean prox = isProximateInnerExpr(compiler, innerExprOpPos); if(prox) return true; } } return false; } static boolean isProximateInnerExpr(Compiler compiler, int opPos) { int op = compiler.getOp(opPos); int innerExprOpPos = opPos+2; switch(op) { case OpCodes.OP_ARGUMENT: if(isProximateInnerExpr(compiler, innerExprOpPos)) return true; break; case OpCodes.OP_VARIABLE: case OpCodes.OP_NUMBERLIT: case OpCodes.OP_LITERAL: case OpCodes.OP_LOCATIONPATH: break; // OK case OpCodes.OP_FUNCTION: boolean isProx = functionProximateOrContainsProximate(compiler, opPos); if(isProx) return true; break; case OpCodes.OP_GT: case OpCodes.OP_GTE: case OpCodes.OP_LT: case OpCodes.OP_LTE: case OpCodes.OP_EQUALS: int leftPos = compiler.getFirstChildPos(op); int rightPos = compiler.getNextOpPos(leftPos); isProx = isProximateInnerExpr(compiler, leftPos); if(isProx) return true; isProx = isProximateInnerExpr(compiler, rightPos); if(isProx) return true; break; default: return true; // be conservative... } return false; } /** * Tell if the predicates need to have proximity knowledge. */ public static boolean mightBeProximate(Compiler compiler, int opPos, int stepType) throws javax.xml.transform.TransformerException { boolean mightBeProximate = false; int argLen; switch (stepType) { case OpCodes.OP_VARIABLE : case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : argLen = compiler.getArgLength(opPos); break; default : argLen = compiler.getArgLengthOfStep(opPos); } int predPos = compiler.getFirstPredicateOpPos(opPos); int count = 0; while (OpCodes.OP_PREDICATE == compiler.getOp(predPos)) { count++; int innerExprOpPos = predPos+2; int predOp = compiler.getOp(innerExprOpPos); switch(predOp) { case OpCodes.OP_VARIABLE: return true; // Would need more smarts to tell if this could be a number or not! case OpCodes.OP_LOCATIONPATH: // OK. break; case OpCodes.OP_NUMBER: case OpCodes.OP_NUMBERLIT: return true; // that's all she wrote! case OpCodes.OP_FUNCTION: boolean isProx = functionProximateOrContainsProximate(compiler, innerExprOpPos); if(isProx) return true; break; case OpCodes.OP_GT: case OpCodes.OP_GTE: case OpCodes.OP_LT: case OpCodes.OP_LTE: case OpCodes.OP_EQUALS: int leftPos = compiler.getFirstChildPos(innerExprOpPos); int rightPos = compiler.getNextOpPos(leftPos); isProx = isProximateInnerExpr(compiler, leftPos); if(isProx) return true; isProx = isProximateInnerExpr(compiler, rightPos); if(isProx) return true; break; default: return true; // be conservative... } predPos = compiler.getNextOpPos(predPos); } return mightBeProximate; } /** * Special purpose function to see if we can optimize the pattern for * a DescendantIterator. * * @param compiler non-null reference to compiler object that has processed * the XPath operations into an opcode map. * @param stepOpCodePos The opcode position for the step. * @param stepIndex The top-level step index withing the iterator. * * @return 32 bits as an integer that give information about the location * path as a whole. * * @throws javax.xml.transform.TransformerException */ private static boolean isOptimizableForDescendantIterator( Compiler compiler, int stepOpCodePos, int stepIndex) throws javax.xml.transform.TransformerException { int stepType; int stepCount = 0; boolean foundDorDS = false; boolean foundSelf = false; boolean foundDS = false; int nodeTestType = OpCodes.NODETYPE_NODE; while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos))) { // The DescendantIterator can only do one node test. If there's more // than one, use another iterator. if(nodeTestType != OpCodes.NODETYPE_NODE && nodeTestType != OpCodes.NODETYPE_ROOT) return false; stepCount++; if(stepCount > 3) return false; boolean mightBeProximate = mightBeProximate(compiler, stepOpCodePos, stepType); if(mightBeProximate) return false; switch (stepType) { case OpCodes.FROM_FOLLOWING : case OpCodes.FROM_FOLLOWING_SIBLINGS : case OpCodes.FROM_PRECEDING : case OpCodes.FROM_PRECEDING_SIBLINGS : case OpCodes.FROM_PARENT : case OpCodes.OP_VARIABLE : case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : case OpCodes.FROM_NAMESPACE : case OpCodes.FROM_ANCESTORS : case OpCodes.FROM_ANCESTORS_OR_SELF : case OpCodes.FROM_ATTRIBUTES : case OpCodes.MATCH_ATTRIBUTE : case OpCodes.MATCH_ANY_ANCESTOR : case OpCodes.MATCH_IMMEDIATE_ANCESTOR : return false; case OpCodes.FROM_ROOT : if(1 != stepCount) return false; break; case OpCodes.FROM_CHILDREN : if(!foundDS && !(foundDorDS && foundSelf)) return false; break; case OpCodes.FROM_DESCENDANTS_OR_SELF : foundDS = true; case OpCodes.FROM_DESCENDANTS : if(3 == stepCount) return false; foundDorDS = true; break; case OpCodes.FROM_SELF : if(1 != stepCount) return false; foundSelf = true; break; default : throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: " // + stepType); } nodeTestType = compiler.getStepTestType(stepOpCodePos); int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos); if (nextStepOpCodePos < 0) break; if(OpCodes.ENDOP != compiler.getOp(nextStepOpCodePos)) { if(compiler.countPredicates(stepOpCodePos) > 0) { return false; } } stepOpCodePos = nextStepOpCodePos; } return true; } /** * Analyze the location path and return 32 bits that give information about * the location path as a whole. See the BIT_XXX constants for meaning about * each of the bits. * * @param compiler non-null reference to compiler object that has processed * the XPath operations into an opcode map. * @param stepOpCodePos The opcode position for the step. * @param stepIndex The top-level step index withing the iterator. * * @return 32 bits as an integer that give information about the location * path as a whole. * * @throws javax.xml.transform.TransformerException */ private static int analyze( Compiler compiler, int stepOpCodePos, int stepIndex) throws javax.xml.transform.TransformerException { int stepType; int stepCount = 0; int analysisResult = 0x00000000; // 32 bits of analysis while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos))) { stepCount++; // String namespace = compiler.getStepNS(stepOpCodePos); // boolean isNSWild = (null != namespace) // ? namespace.equals(NodeTest.WILD) : false; // String localname = compiler.getStepLocalName(stepOpCodePos); // boolean isWild = (null != localname) ? localname.equals(NodeTest.WILD) : false; boolean predAnalysis = analyzePredicate(compiler, stepOpCodePos, stepType); if (predAnalysis) analysisResult |= BIT_PREDICATE; switch (stepType) { case OpCodes.OP_VARIABLE : case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : analysisResult |= BIT_FILTER; break; case OpCodes.FROM_ROOT : analysisResult |= BIT_ROOT; break; case OpCodes.FROM_ANCESTORS : analysisResult |= BIT_ANCESTOR; break; case OpCodes.FROM_ANCESTORS_OR_SELF : analysisResult |= BIT_ANCESTOR_OR_SELF; break; case OpCodes.FROM_ATTRIBUTES : analysisResult |= BIT_ATTRIBUTE; break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?