📄 walkerfactory.java
字号:
{ return (0 != (analysis & BIT_NODETEST_ANY)); } public static boolean walksAncestors(int analysis) { return isSet(analysis, BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF); } public static boolean walksAttributes(int analysis) { return (0 != (analysis & BIT_ATTRIBUTE)); } public static boolean walksNamespaces(int analysis) { return (0 != (analysis & BIT_NAMESPACE)); } public static boolean walksChildren(int analysis) { return (0 != (analysis & BIT_CHILD)); } public static boolean walksDescendants(int analysis) { return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF); } public static boolean walksSubtree(int analysis) { return isSet(analysis, BIT_DESCENDANT | BIT_DESCENDANT_OR_SELF | BIT_CHILD); } public static boolean walksSubtreeOnlyMaybeAbsolute(int analysis) { return walksSubtree(analysis) && !walksExtraNodes(analysis) && !walksUp(analysis) && !walksSideways(analysis) ; } public static boolean walksSubtreeOnly(int analysis) { return walksSubtreeOnlyMaybeAbsolute(analysis) && !isAbsolute(analysis) ; } public static boolean walksFilteredList(int analysis) { return isSet(analysis, BIT_FILTER); } public static boolean walksSubtreeOnlyFromRootOrContext(int analysis) { return walksSubtree(analysis) && !walksExtraNodes(analysis) && !walksUp(analysis) && !walksSideways(analysis) && !isSet(analysis, BIT_FILTER) ; } public static boolean walksInDocOrder(int analysis) { return (walksSubtreeOnlyMaybeAbsolute(analysis) || walksExtraNodesOnly(analysis) || walksFollowingOnlyMaybeAbsolute(analysis)) && !isSet(analysis, BIT_FILTER) ; } public static boolean walksFollowingOnlyMaybeAbsolute(int analysis) { return isSet(analysis, BIT_SELF | BIT_FOLLOWING_SIBLING | BIT_FOLLOWING) && !walksSubtree(analysis) && !walksUp(analysis) && !walksSideways(analysis) ; } public static boolean walksUp(int analysis) { return isSet(analysis, BIT_PARENT | BIT_ANCESTOR | BIT_ANCESTOR_OR_SELF); } public static boolean walksSideways(int analysis) { return isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING | BIT_PRECEDING | BIT_PRECEDING_SIBLING); } public static boolean walksExtraNodes(int analysis) { return isSet(analysis, BIT_NAMESPACE | BIT_ATTRIBUTE); } public static boolean walksExtraNodesOnly(int analysis) { return walksExtraNodes(analysis) && !isSet(analysis, BIT_SELF) && !walksSubtree(analysis) && !walksUp(analysis) && !walksSideways(analysis) && !isAbsolute(analysis) ; } public static boolean isAbsolute(int analysis) { return isSet(analysis, BIT_ROOT | BIT_FILTER); } public static boolean walksChildrenOnly(int analysis) { return walksChildren(analysis) && !isSet(analysis, BIT_SELF) && !walksExtraNodes(analysis) && !walksDescendants(analysis) && !walksUp(analysis) && !walksSideways(analysis) && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT)) ; } public static boolean walksChildrenAndExtraAndSelfOnly(int analysis) { return walksChildren(analysis) && !walksDescendants(analysis) && !walksUp(analysis) && !walksSideways(analysis) && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT)) ; } public static boolean walksDescendantsAndExtraAndSelfOnly(int analysis) { return !walksChildren(analysis) && walksDescendants(analysis) && !walksUp(analysis) && !walksSideways(analysis) && (!isAbsolute(analysis) || isSet(analysis, BIT_ROOT)) ; } public static boolean walksSelfOnly(int analysis) { return isSet(analysis, BIT_SELF) && !walksSubtree(analysis) && !walksUp(analysis) && !walksSideways(analysis) && !isAbsolute(analysis) ; } public static boolean walksUpOnly(int analysis) { return !walksSubtree(analysis) && walksUp(analysis) && !walksSideways(analysis) && !isAbsolute(analysis) ; } public static boolean walksDownOnly(int analysis) { return walksSubtree(analysis) && !walksUp(analysis) && !walksSideways(analysis) && !isAbsolute(analysis) ; } public static boolean walksDownExtraOnly(int analysis) { return walksSubtree(analysis) && walksExtraNodes(analysis) && !walksUp(analysis) && !walksSideways(analysis) && !isAbsolute(analysis) ; } public static boolean canSkipSubtrees(int analysis) { return isSet(analysis, BIT_CHILD) | walksSideways(analysis); } public static boolean canCrissCross(int analysis) { // This could be done faster. Coded for clarity. if(walksSelfOnly(analysis)) return false; else if(walksDownOnly(analysis) && !canSkipSubtrees(analysis)) return false; else if(walksChildrenAndExtraAndSelfOnly(analysis)) return false; else if(walksDescendantsAndExtraAndSelfOnly(analysis)) return false; else if(walksUpOnly(analysis)) return false; else if(walksExtraNodesOnly(analysis)) return false; else if(walksSubtree(analysis) && (walksSideways(analysis) || walksUp(analysis) || canSkipSubtrees(analysis))) return true; else return false; } /** * Tell if the pattern can be 'walked' with the iteration steps in natural * document order, without duplicates. * * @param analysis The general analysis of the pattern. * * @return true if the walk can be done in natural order. * * @throws javax.xml.transform.TransformerException */ static public boolean isNaturalDocOrder(int analysis) { if(canCrissCross(analysis) || isSet(analysis, BIT_NAMESPACE) || walksFilteredList(analysis)) return false; if(walksInDocOrder(analysis)) return true; return false; } /** * Tell if the pattern can be 'walked' with the iteration steps in natural * document order, without duplicates. * * @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. * @param analysis The general analysis of the pattern. * * @return true if the walk can be done in natural order. * * @throws javax.xml.transform.TransformerException */ private static boolean isNaturalDocOrder( Compiler compiler, int stepOpCodePos, int stepIndex, int analysis) throws javax.xml.transform.TransformerException { if(canCrissCross(analysis)) return false; // Namespaces can present some problems, so just punt if we're looking for // these. if(isSet(analysis, BIT_NAMESPACE)) return false; // The following, preceding, following-sibling, and preceding sibling can // be found in doc order if we get to this point, but if they occur // together, they produce // duplicates, so it's better for us to eliminate this case so we don't // have to check for duplicates during runtime if we're using a // WalkingIterator. if(isSet(analysis, BIT_FOLLOWING | BIT_FOLLOWING_SIBLING) && isSet(analysis, BIT_PRECEDING | BIT_PRECEDING_SIBLING)) return false; // OK, now we have to check for select="@*/axis::*" patterns, which // can also cause duplicates to happen. But select="axis*/@::*" patterns // are OK, as are select="@foo/axis::*" patterns. // Unfortunately, we can't do this just via the analysis bits. int stepType; int stepCount = 0; boolean foundWildAttribute = false; // Steps that can traverse anything other than down a // subtree or that can produce duplicates when used in // combonation are counted with this variable. int potentialDuplicateMakingStepCount = 0; while (OpCodes.ENDOP != (stepType = compiler.getOp(stepOpCodePos))) { stepCount++; switch (stepType) { case OpCodes.FROM_ATTRIBUTES : case OpCodes.MATCH_ATTRIBUTE : if(foundWildAttribute) // Maybe not needed, but be safe. return false; // This doesn't seem to work as a test for wild card. Hmph. // int nodeTestType = compiler.getStepTestType(stepOpCodePos); String localName = compiler.getStepLocalName(stepOpCodePos); // System.err.println("localName: "+localName); if(localName.equals("*")) { foundWildAttribute = true; } break; 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.MATCH_ANY_ANCESTOR : case OpCodes.MATCH_IMMEDIATE_ANCESTOR : case OpCodes.FROM_DESCENDANTS_OR_SELF : case OpCodes.FROM_DESCENDANTS : if(potentialDuplicateMakingStepCount > 0) return false; potentialDuplicateMakingStepCount++; case OpCodes.FROM_ROOT : case OpCodes.FROM_CHILDREN : case OpCodes.FROM_SELF : if(foundWildAttribute) return false; break; default : throw new RuntimeException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_NULL_ERROR_HANDLER, new Object[]{Integer.toString(stepType)})); //"Programmer's assertion: unknown opcode: " // + stepType); } int nextStepOpCodePos = compiler.getNextStepPos(stepOpCodePos); if (nextStepOpCodePos < 0) break; stepOpCodePos = nextStepOpCodePos; } return true; } public static boolean isOneStep(int analysis) { return (analysis & BITS_COUNT) == 0x00000001; } public static int getStepCount(int analysis) { return (analysis & BITS_COUNT); } /** * First 8 bits are the number of top-level location steps. Hopefully * there will never be more that 255 location steps!!! */ public static final int BITS_COUNT = 0x000000FF; /** 4 bits are reserved for future use. */ public static final int BITS_RESERVED = 0x00000F00; /** Bit is on if the expression contains a top-level predicate. */ public static final int BIT_PREDICATE = (0x00001000); /** Bit is on if any of the walkers contain an ancestor step. */ public static final int BIT_ANCESTOR = (0x00001000 << 1); /** Bit is on if any of the walkers contain an ancestor-or-self step. */ public static final int BIT_ANCESTOR_OR_SELF = (0x00001000 << 2); /** Bit is on if any of the walkers contain an attribute step. */ public static final int BIT_ATTRIBUTE = (0x00001000 << 3); /** Bit is on if any of the walkers contain a child step. */ public static final int BIT_CHILD = (0x00001000 << 4); /** Bit is on if any of the walkers contain a descendant step. */ public static final int BIT_DESCENDANT = (0x00001000 << 5); /** Bit is on if any of the walkers contain a descendant-or-self step. */ public static final int BIT_DESCENDANT_OR_SELF = (0x00001000 << 6); /** Bit is on if any of the walkers contain a following step. */ public static final int BIT_FOLLOWING = (0x00001000 << 7); /** Bit is on if any of the walkers contain a following-sibiling step. */ public static final int BIT_FOLLOWING_SIBLING = (0x00001000 << 8); /** Bit is on if any of the walkers contain a namespace step. */ public static final int BIT_NAMESPACE = (0x00001000 << 9); /** Bit is on if any of the walkers contain a parent step. */ public static final int BIT_PARENT = (0x00001000 << 10); /** Bit is on if any of the walkers contain a preceding step. */ public static final int BIT_PRECEDING = (0x00001000 << 11); /** Bit is on if any of the walkers contain a preceding-sibling step. */ public static final int BIT_PRECEDING_SIBLING = (0x00001000 << 12); /** Bit is on if any of the walkers contain a self step. */ public static final int BIT_SELF = (0x00001000 << 13); /** * Bit is on if any of the walkers contain a filter (i.e. id(), extension * function, etc.) step. */ public static final int BIT_FILTER = (0x00001000 << 14); /** Bit is on if any of the walkers contain a root step. */ public static final int BIT_ROOT = (0x00001000 << 15); /** * If any of these bits are on, the expression may likely traverse outside * the given subtree. */ public static final int BITMASK_TRAVERSES_OUTSIDE_SUBTREE = (BIT_NAMESPACE // ?? | BIT_PRECEDING_SIBLING | BIT_PRECEDING | BIT_FOLLOWING_SIBLING | BIT_FOLLOWING | BIT_PARENT // except parent of attrs. | BIT_ANCESTOR_OR_SELF | BIT_ANCESTOR | BIT_FILTER | BIT_ROOT); /** * Bit is on if any of the walkers can go backwards in document * order from the context node. */ public static final int BIT_BACKWARDS_SELF = (0x00001000 << 16); /** Found "//foo" pattern */ public static final int BIT_ANY_DESCENDANT_FROM_ROOT = (0x00001000 << 17); /** * Bit is on if any of the walkers contain an node() test. This is * really only useful if the count is 1. */ public static final int BIT_NODETEST_ANY = (0x00001000 << 18); // can't go higher than 18! /** Bit is on if the expression is a match pattern. */ public static final int BIT_MATCH_PATTERN = (0x00001000 << 19);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -