walkerfactory.java
来自「java jdk 1.4的源码」· Java 代码 · 共 1,871 行 · 第 1/5 页
JAVA
1,871 行
case OpCodes.FROM_NAMESPACE : analysisResult |= BIT_NAMESPACE; break; case OpCodes.FROM_CHILDREN : analysisResult |= BIT_CHILD; break; case OpCodes.FROM_DESCENDANTS : analysisResult |= BIT_DESCENDANT; break; case OpCodes.FROM_DESCENDANTS_OR_SELF : // Use a special bit to to make sure we get the right analysis of "//foo". if (2 == stepCount && BIT_ROOT == analysisResult) { analysisResult |= BIT_ANY_DESCENDANT_FROM_ROOT; } analysisResult |= BIT_DESCENDANT_OR_SELF; break; case OpCodes.FROM_FOLLOWING : analysisResult |= BIT_FOLLOWING; break; case OpCodes.FROM_FOLLOWING_SIBLINGS : analysisResult |= BIT_FOLLOWING_SIBLING; break; case OpCodes.FROM_PRECEDING : analysisResult |= BIT_PRECEDING; break; case OpCodes.FROM_PRECEDING_SIBLINGS : analysisResult |= BIT_PRECEDING_SIBLING; break; case OpCodes.FROM_PARENT : analysisResult |= BIT_PARENT; break; case OpCodes.FROM_SELF : analysisResult |= BIT_SELF; break; case OpCodes.MATCH_ATTRIBUTE : analysisResult |= (BIT_MATCH_PATTERN | BIT_ATTRIBUTE); break; case OpCodes.MATCH_ANY_ANCESTOR : analysisResult |= (BIT_MATCH_PATTERN | BIT_ANCESTOR); break; case OpCodes.MATCH_IMMEDIATE_ANCESTOR : analysisResult |= (BIT_MATCH_PATTERN | BIT_PARENT); break; default : throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: " //+ stepType); } if (OpCodes.NODETYPE_NODE == compiler.getOp(stepOpCodePos + 3)) // child::node() { analysisResult |= BIT_NODETEST_ANY; } stepOpCodePos = compiler.getNextStepPos(stepOpCodePos); if (stepOpCodePos < 0) break; } analysisResult |= (stepCount & BITS_COUNT); return analysisResult; } /** * Tell if the given axis goes downword. Bogus name, if you can think of * a better one, please do tell. This really has to do with inverting * attribute axis. * @param axis One of Axis.XXX. * @return true if the axis is not a child axis and does not go up from * the axis root. */ public static boolean isDownwardAxisOfMany(int axis) { return ((Axis.DESCENDANTORSELF == axis) || (Axis.DESCENDANT == axis) || (Axis.FOLLOWING == axis) // || (Axis.FOLLOWINGSIBLING == axis) || (Axis.PRECEDING == axis) // || (Axis.PRECEDINGSIBLING == axis) ); } /** * Read a <a href="http://www.w3.org/TR/xpath#location-paths">LocationPath</a> * as a generalized match pattern. What this means is that the LocationPath * is read backwards, as a test on a given node, to see if it matches the * criteria of the selection, and ends up at the context node. Essentially, * this is a backwards query from a given node, to find the context node. * <p>So, the selection "foo/daz[2]" is, in non-abreviated expanded syntax, * "self::node()/following-sibling::foo/child::daz[position()=2]". * Taking this as a match pattern for a probable node, it works out to * "self::daz/parent::foo[child::daz[position()=2 and isPrevStepNode()] * precedingSibling::node()[isContextNodeOfLocationPath()]", adding magic * isPrevStepNode and isContextNodeOfLocationPath operations. Predicates in * the location path have to be executed by the following step, * because they have to know the context of their execution. * * @param mpi The MatchPatternIterator to which the steps will be attached. * @param compiler The compiler that holds the syntax tree/op map to * construct from. * @param stepOpCodePos The current op code position within the opmap. * @param stepIndex The top-level step index withing the iterator. * * @return A StepPattern object, which may contain relative StepPatterns. * * @throws javax.xml.transform.TransformerException */ static StepPattern loadSteps( MatchPatternIterator mpi, Compiler compiler, int stepOpCodePos, int stepIndex) throws javax.xml.transform.TransformerException { if (DEBUG_PATTERN_CREATION) { System.out.println("================"); System.out.println("loadSteps for: "+compiler.getPatternString()); } int stepType; StepPattern step = null; StepPattern firstStep = null, prevStep = null; int analysis = analyze(compiler, stepOpCodePos, stepIndex); while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos))) { step = createDefaultStepPattern(compiler, stepOpCodePos, mpi, analysis, firstStep, prevStep); if (null == firstStep) { firstStep = step; } else { //prevStep.setNextWalker(step); step.setRelativePathPattern(prevStep); } prevStep = step; stepOpCodePos = compiler.getNextStepPos(stepOpCodePos); if (stepOpCodePos < 0) break; } int axis = Axis.SELF; int paxis = Axis.SELF; StepPattern tail = step; for (StepPattern pat = step; null != pat; pat = pat.getRelativePathPattern()) { int nextAxis = pat.getAxis(); //int nextPaxis = pat.getPredicateAxis(); pat.setAxis(axis); // The predicate axis can't be moved!!! Test Axes103 // pat.setPredicateAxis(paxis); // If we have an attribute or namespace axis that went up, then // it won't find the attribute in the inverse, since the select-to-match // axes are not invertable (an element is a parent of an attribute, but // and attribute is not a child of an element). // If we don't do the magic below, then "@*/ancestor-or-self::*" gets // inverted for match to "self::*/descendant-or-self::@*/parent::node()", // which obviously won't work. // So we will rewrite this as: // "self::*/descendant-or-self::*/attribute::*/parent::node()" // Child has to be rewritten a little differently: // select: "@*/parent::*" // inverted match: "self::*/child::@*/parent::node()" // rewrite: "self::*/attribute::*/parent::node()" // Axes that go down in the select, do not have to have special treatment // in the rewrite. The following inverted match will still not select // anything. // select: "@*/child::*" // inverted match: "self::*/parent::@*/parent::node()" // Lovely business, this. // -sb int whatToShow = pat.getWhatToShow(); if(whatToShow == DTMFilter.SHOW_ATTRIBUTE || whatToShow == DTMFilter.SHOW_NAMESPACE) { int newAxis = (whatToShow == DTMFilter.SHOW_ATTRIBUTE) ? Axis.ATTRIBUTE : Axis.NAMESPACE; if(isDownwardAxisOfMany(axis)) { StepPattern attrPat = new StepPattern(whatToShow, pat.getNamespace(), pat.getLocalName(), //newAxis, pat.getPredicateAxis); newAxis, 0); // don't care about the predicate axis XNumber score = pat.getStaticScore(); pat.setNamespace(null); pat.setLocalName(NodeTest.WILD); attrPat.setPredicates(pat.getPredicates()); pat.setPredicates(null); pat.setWhatToShow(DTMFilter.SHOW_ELEMENT); StepPattern rel = pat.getRelativePathPattern(); pat.setRelativePathPattern(attrPat); attrPat.setRelativePathPattern(rel); attrPat.setStaticScore(score); // This is needed to inverse a following pattern, because of the // wacky Xalan rules for following from an attribute. See axes108. // By these rules, following from an attribute is not strictly // inverseable. if(Axis.PRECEDING == pat.getAxis()) pat.setAxis(Axis.PRECEDINGANDANCESTOR); else if(Axis.DESCENDANT == pat.getAxis()) pat.setAxis(Axis.DESCENDANTORSELF); pat = attrPat; } else if(Axis.CHILD == pat.getAxis()) { // In this case just change the axis. // pat.setWhatToShow(whatToShow); pat.setAxis(Axis.ATTRIBUTE); } } axis = nextAxis; //paxis = nextPaxis; tail = pat; } if(axis < Axis.ALL) { StepPattern selfPattern = new ContextMatchStepPattern(axis, paxis); // We need to keep the new nodetest from affecting the score... XNumber score = tail.getStaticScore(); tail.setRelativePathPattern(selfPattern); tail.setStaticScore(score); selfPattern.setStaticScore(score); } if (DEBUG_PATTERN_CREATION) { System.out.println("Done loading steps: "+step.toString()); System.out.println(""); } return step; // start from last pattern?? //firstStep; } /** * Create a StepPattern that is contained within a LocationPath. * * * @param compiler The compiler that holds the syntax tree/op map to * construct from. * @param stepOpCodePos The current op code position within the opmap. * @param mpi The MatchPatternIterator to which the steps will be attached. * @param analysis 32 bits of analysis, from which the type of AxesWalker * may be influenced. * @param tail The step that is the first step analyzed, but the last * step in the relative match linked list, i.e. the tail. * May be null. * @param head The step that is the current head of the relative * match step linked list. * May be null. * * @return the head of the list. * * @throws javax.xml.transform.TransformerException */ private static StepPattern createDefaultStepPattern( Compiler compiler, int opPos, MatchPatternIterator mpi, int analysis, StepPattern tail, StepPattern head) throws javax.xml.transform.TransformerException { int stepType = compiler.getOp(opPos); boolean simpleInit = false; int totalNumberWalkers = (analysis & BITS_COUNT); boolean prevIsOneStepDown = true; int firstStepPos = compiler.getFirstChildPos(opPos); int whatToShow = compiler.getWhatToShow(opPos); StepPattern ai = null; int axis, predicateAxis; switch (stepType) { case OpCodes.OP_VARIABLE : case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : prevIsOneStepDown = false; Expression expr; switch (stepType) { case OpCodes.OP_VARIABLE : case OpCodes.OP_EXTFUNCTION : case OpCodes.OP_FUNCTION : case OpCodes.OP_GROUP : expr = compiler.compile(opPos); break; default : expr = compiler.compile(opPos + 2); } axis = Axis.FILTEREDLIST; predicateAxis = Axis.FILTEREDLIST; ai = new FunctionPattern(expr, axis, predicateAxis); simpleInit = true; break; case OpCodes.FROM_ROOT : whatToShow = DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT; axis = Axis.ROOT; predicateAxis = Axis.ROOT; ai = new StepPattern(DTMFilter.SHOW_DOCUMENT | DTMFilter.SHOW_DOCUMENT_FRAGMENT, axis, predicateAxis); break; case OpCodes.FROM_ATTRIBUTES : whatToShow = DTMFilter.SHOW_ATTRIBUTE; axis = Axis.PARENT; predicateAxis = Axis.ATTRIBUTE; // ai = new StepPattern(whatToShow, Axis.SELF, Axis.SELF); break; case OpCodes.FROM_NAMESPACE : whatToShow = DTMFilter.SHOW_NAMESPACE; axis = Axis.PARENT; predicateAxis = Axis.NAMESPACE; // ai = new StepPattern(whatToShow, axis, predicateAxis); break; case OpCodes.FROM_ANCESTORS : axis = Axis.DESCENDANT; predicateAxis = Axis.ANCESTOR; break; case OpCodes.FROM_CHILDREN : axis = Axis.PARENT; predicateAxis = Axis.CHILD; break; case OpCodes.FROM_ANCESTORS_OR_SELF : axis = Axis.DESCENDANTORSELF; predicateAxis = Axis.ANCESTORORSELF; break; case OpCodes.FROM_SELF : axis = Axis.SELF; predicateAxis = Axis.SELF; break; case OpCodes.FROM_PARENT : axis = Axis.CHILD; predicateAxis = Axis.PARENT; break; case OpCodes.FROM_PRECEDING_SIBLINGS : axis = Axis.FOLLOWINGSIBLING; predicateAxis = Axis.PRECEDINGSIBLING; break; case OpCodes.FROM_PRECEDING : axis = Axis.FOLLOWING; predicateAxis = Axis.PRECEDING; break; case OpCodes.FROM_FOLLOWING_SIBLINGS : axis = Axis.PRECEDINGSIBLING; predicateAxis = Axis.FOLLOWINGSIBLING; break; case OpCodes.FROM_FOLLOWING : axis = Axis.PRECEDING; predicateAxis = Axis.FOLLOWING; break; case OpCodes.FROM_DESCENDANTS_OR_SELF : axis = Axis.ANCESTORORSELF; predicateAxis = Axis.DESCENDANTORSELF; break;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?