Source Code Cross Referenced for DTMDefaultBaseTraversers.java in  » XML » xalan » org » apache » xml » dtm » ref » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » XML » xalan » org.apache.xml.dtm.ref 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 1999-2004 The Apache Software Foundation.
0003:         *
0004:         * Licensed under the Apache License, Version 2.0 (the "License");
0005:         * you may not use this file except in compliance with the License.
0006:         * You may obtain a copy of the License at
0007:         *
0008:         *     http://www.apache.org/licenses/LICENSE-2.0
0009:         *
0010:         * Unless required by applicable law or agreed to in writing, software
0011:         * distributed under the License is distributed on an "AS IS" BASIS,
0012:         * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013:         * See the License for the specific language governing permissions and
0014:         * limitations under the License.
0015:         */
0016:        /*
0017:         * $Id: DTMDefaultBaseTraversers.java,v 1.21 2005/01/24 00:34:35 mcnamara Exp $
0018:         */
0019:        package org.apache.xml.dtm.ref;
0020:
0021:        import org.apache.xml.dtm.*;
0022:
0023:        import javax.xml.transform.Source;
0024:
0025:        import org.apache.xml.utils.XMLStringFactory;
0026:
0027:        import org.apache.xml.res.XMLErrorResources;
0028:        import org.apache.xml.res.XMLMessages;
0029:        import org.apache.xalan.xsltc.dom.NodeCounter;
0030:
0031:        /**
0032:         * This class implements the traversers for DTMDefaultBase.
0033:         *
0034:         * PLEASE NOTE that the public interface for all traversers should be
0035:         * in terms of DTM Node Handles... but they may use the internal node
0036:         * identity indices within their logic, for efficiency's sake. Be very
0037:         * careful to avoid confusing these when maintaining this code.
0038:         * */
0039:        public abstract class DTMDefaultBaseTraversers extends DTMDefaultBase {
0040:
0041:            /**
0042:             * Construct a DTMDefaultBaseTraversers object from a DOM node.
0043:             *
0044:             * @param mgr The DTMManager who owns this DTM.
0045:             * @param source The object that is used to specify the construction source.
0046:             * @param dtmIdentity The DTM identity ID for this DTM.
0047:             * @param whiteSpaceFilter The white space filter for this DTM, which may
0048:             *                         be null.
0049:             * @param xstringfactory The factory to use for creating XMLStrings.
0050:             * @param doIndexing true if the caller considers it worth it to use
0051:             *                   indexing schemes.
0052:             */
0053:            public DTMDefaultBaseTraversers(DTMManager mgr, Source source,
0054:                    int dtmIdentity, DTMWSFilter whiteSpaceFilter,
0055:                    XMLStringFactory xstringfactory, boolean doIndexing) {
0056:                super (mgr, source, dtmIdentity, whiteSpaceFilter,
0057:                        xstringfactory, doIndexing);
0058:            }
0059:
0060:            /**
0061:             * Construct a DTMDefaultBaseTraversers object from a DOM node.
0062:             *
0063:             * @param mgr The DTMManager who owns this DTM.
0064:             * @param source The object that is used to specify the construction source.
0065:             * @param dtmIdentity The DTM identity ID for this DTM.
0066:             * @param whiteSpaceFilter The white space filter for this DTM, which may
0067:             *                         be null.
0068:             * @param xstringfactory The factory to use for creating XMLStrings.
0069:             * @param doIndexing true if the caller considers it worth it to use
0070:             *                   indexing schemes.
0071:             * @param blocksize The block size of the DTM.
0072:             * @param usePrevsib true if we want to build the previous sibling node array.
0073:             * @param newNameTable true if we want to use a new ExpandedNameTable for this DTM.
0074:             */
0075:            public DTMDefaultBaseTraversers(DTMManager mgr, Source source,
0076:                    int dtmIdentity, DTMWSFilter whiteSpaceFilter,
0077:                    XMLStringFactory xstringfactory, boolean doIndexing,
0078:                    int blocksize, boolean usePrevsib, boolean newNameTable) {
0079:                super (mgr, source, dtmIdentity, whiteSpaceFilter,
0080:                        xstringfactory, doIndexing, blocksize, usePrevsib,
0081:                        newNameTable);
0082:            }
0083:
0084:            /**
0085:             * This returns a stateless "traverser", that can navigate
0086:             * over an XPath axis, though perhaps not in document order.
0087:             *
0088:             * @param axis One of Axes.ANCESTORORSELF, etc.
0089:             *
0090:             * @return A DTMAxisTraverser, or null if the given axis isn't supported.
0091:             */
0092:            public DTMAxisTraverser getAxisTraverser(final int axis) {
0093:
0094:                DTMAxisTraverser traverser;
0095:
0096:                if (null == m_traversers) // Cache of stateless traversers for this DTM
0097:                {
0098:                    m_traversers = new DTMAxisTraverser[Axis.getNamesLength()];
0099:                    traverser = null;
0100:                } else {
0101:                    traverser = m_traversers[axis]; // Share/reuse existing traverser
0102:
0103:                    if (traverser != null)
0104:                        return traverser;
0105:                }
0106:
0107:                switch (axis) // Generate new traverser
0108:                {
0109:                case Axis.ANCESTOR:
0110:                    traverser = new AncestorTraverser();
0111:                    break;
0112:                case Axis.ANCESTORORSELF:
0113:                    traverser = new AncestorOrSelfTraverser();
0114:                    break;
0115:                case Axis.ATTRIBUTE:
0116:                    traverser = new AttributeTraverser();
0117:                    break;
0118:                case Axis.CHILD:
0119:                    traverser = new ChildTraverser();
0120:                    break;
0121:                case Axis.DESCENDANT:
0122:                    traverser = new DescendantTraverser();
0123:                    break;
0124:                case Axis.DESCENDANTORSELF:
0125:                    traverser = new DescendantOrSelfTraverser();
0126:                    break;
0127:                case Axis.FOLLOWING:
0128:                    traverser = new FollowingTraverser();
0129:                    break;
0130:                case Axis.FOLLOWINGSIBLING:
0131:                    traverser = new FollowingSiblingTraverser();
0132:                    break;
0133:                case Axis.NAMESPACE:
0134:                    traverser = new NamespaceTraverser();
0135:                    break;
0136:                case Axis.NAMESPACEDECLS:
0137:                    traverser = new NamespaceDeclsTraverser();
0138:                    break;
0139:                case Axis.PARENT:
0140:                    traverser = new ParentTraverser();
0141:                    break;
0142:                case Axis.PRECEDING:
0143:                    traverser = new PrecedingTraverser();
0144:                    break;
0145:                case Axis.PRECEDINGSIBLING:
0146:                    traverser = new PrecedingSiblingTraverser();
0147:                    break;
0148:                case Axis.SELF:
0149:                    traverser = new SelfTraverser();
0150:                    break;
0151:                case Axis.ALL:
0152:                    traverser = new AllFromRootTraverser();
0153:                    break;
0154:                case Axis.ALLFROMNODE:
0155:                    traverser = new AllFromNodeTraverser();
0156:                    break;
0157:                case Axis.PRECEDINGANDANCESTOR:
0158:                    traverser = new PrecedingAndAncestorTraverser();
0159:                    break;
0160:                case Axis.DESCENDANTSFROMROOT:
0161:                    traverser = new DescendantFromRootTraverser();
0162:                    break;
0163:                case Axis.DESCENDANTSORSELFFROMROOT:
0164:                    traverser = new DescendantOrSelfFromRootTraverser();
0165:                    break;
0166:                case Axis.ROOT:
0167:                    traverser = new RootTraverser();
0168:                    break;
0169:                case Axis.FILTEREDLIST:
0170:                    return null; // Don't want to throw an exception for this one.
0171:                default:
0172:                    throw new DTMException(XMLMessages.createXMLMessage(
0173:                            XMLErrorResources.ER_UNKNOWN_AXIS_TYPE,
0174:                            new Object[] { Integer.toString(axis) })); //"Unknown axis traversal type: "+axis);
0175:                }
0176:
0177:                if (null == traverser)
0178:                    throw new DTMException(XMLMessages.createXMLMessage(
0179:                            XMLErrorResources.ER_AXIS_TRAVERSER_NOT_SUPPORTED,
0180:                            new Object[] { Axis.getNames(axis) }));
0181:                // "Axis traverser not supported: "
0182:                //                       + Axis.names[axis]);
0183:
0184:                m_traversers[axis] = traverser;
0185:
0186:                return traverser;
0187:            }
0188:
0189:            /**
0190:             * Implements traversal of the Ancestor access, in reverse document order.
0191:             */
0192:            private class AncestorTraverser extends DTMAxisTraverser {
0193:
0194:                /**
0195:                 * Traverse to the next node after the current node.
0196:                 *
0197:                 * @param context The context node if this iteration.
0198:                 * @param current The current node of the iteration.
0199:                 *
0200:                 * @return the next node in the iteration, or DTM.NULL.
0201:                 */
0202:                public int next(int context, int current) {
0203:                    return getParent(current);
0204:                }
0205:
0206:                /**
0207:                 * Traverse to the next node after the current node that is matched
0208:                 * by the expanded type ID.
0209:                 *
0210:                 * @param context The context node of this iteration.
0211:                 * @param current The current node of the iteration.
0212:                 * @param expandedTypeID The expanded type ID that must match.
0213:                 *
0214:                 * @return the next node in the iteration, or DTM.NULL.
0215:                 */
0216:                public int next(int context, int current, int expandedTypeID) {
0217:                    // Process using identities
0218:                    current = makeNodeIdentity(current);
0219:
0220:                    while (DTM.NULL != (current = m_parent.elementAt(current))) {
0221:                        if (m_exptype.elementAt(current) == expandedTypeID)
0222:                            return makeNodeHandle(current);
0223:                    }
0224:
0225:                    return NULL;
0226:                }
0227:            }
0228:
0229:            /**
0230:             * Implements traversal of the Ancestor access, in reverse document order.
0231:             */
0232:            private class AncestorOrSelfTraverser extends AncestorTraverser {
0233:
0234:                /**
0235:                 * By the nature of the stateless traversal, the context node can not be
0236:                 * returned or the iteration will go into an infinate loop.  To see if
0237:                 * the self node should be processed, use this function.
0238:                 *
0239:                 * @param context The context node of this traversal.
0240:                 *
0241:                 * @return the first node in the traversal.
0242:                 */
0243:                public int first(int context) {
0244:                    return context;
0245:                }
0246:
0247:                /**
0248:                 * By the nature of the stateless traversal, the context node can not be
0249:                 * returned or the iteration will go into an infinate loop.  To see if
0250:                 * the self node should be processed, use this function.  If the context
0251:                 * node does not match the expanded type ID, this function will return
0252:                 * false.
0253:                 *
0254:                 * @param context The context node of this traversal.
0255:                 * @param expandedTypeID The expanded type ID that must match.
0256:                 *
0257:                 * @return the first node in the traversal.
0258:                 */
0259:                public int first(int context, int expandedTypeID) {
0260:                    return (getExpandedTypeID(context) == expandedTypeID) ? context
0261:                            : next(context, context, expandedTypeID);
0262:                }
0263:            }
0264:
0265:            /**
0266:             * Implements traversal of the Attribute access
0267:             */
0268:            private class AttributeTraverser extends DTMAxisTraverser {
0269:
0270:                /**
0271:                 * Traverse to the next node after the current node.
0272:                 *
0273:                 * @param context The context node of this iteration.
0274:                 * @param current The current node of the iteration.
0275:                 *
0276:                 * @return the next node in the iteration, or DTM.NULL.
0277:                 */
0278:                public int next(int context, int current) {
0279:                    return (context == current) ? getFirstAttribute(context)
0280:                            : getNextAttribute(current);
0281:                }
0282:
0283:                /**
0284:                 * Traverse to the next node after the current node that is matched
0285:                 * by the expanded type ID.
0286:                 *
0287:                 * @param context The context node of this iteration.
0288:                 * @param current The current node of the iteration.
0289:                 * @param expandedTypeID The expanded type ID that must match.
0290:                 *
0291:                 * @return the next node in the iteration, or DTM.NULL.
0292:                 */
0293:                public int next(int context, int current, int expandedTypeID) {
0294:
0295:                    current = (context == current) ? getFirstAttribute(context)
0296:                            : getNextAttribute(current);
0297:
0298:                    do {
0299:                        if (getExpandedTypeID(current) == expandedTypeID)
0300:                            return current;
0301:                    } while (DTM.NULL != (current = getNextAttribute(current)));
0302:
0303:                    return NULL;
0304:                }
0305:            }
0306:
0307:            /**
0308:             * Implements traversal of the Ancestor access, in reverse document order.
0309:             */
0310:            private class ChildTraverser extends DTMAxisTraverser {
0311:
0312:                /**
0313:                 * Get the next indexed node that matches the expanded type ID.  Before 
0314:                 * calling this function, one should first call 
0315:                 * {@link #isIndexed(int) isIndexed} to make sure that the index can 
0316:                 * contain nodes that match the given expanded type ID.
0317:                 *
0318:                 * @param axisRoot The root identity of the axis.
0319:                 * @param nextPotential The node found must match or occur after this node.
0320:                 * @param expandedTypeID The expanded type ID for the request.
0321:                 *
0322:                 * @return The node ID or NULL if not found.
0323:                 */
0324:                protected int getNextIndexed(int axisRoot, int nextPotential,
0325:                        int expandedTypeID) {
0326:
0327:                    int nsIndex = m_expandedNameTable
0328:                            .getNamespaceID(expandedTypeID);
0329:                    int lnIndex = m_expandedNameTable
0330:                            .getLocalNameID(expandedTypeID);
0331:
0332:                    for (;;) {
0333:                        int nextID = findElementFromIndex(nsIndex, lnIndex,
0334:                                nextPotential);
0335:
0336:                        if (NOTPROCESSED != nextID) {
0337:                            int parentID = m_parent.elementAt(nextID);
0338:
0339:                            // Is it a child?
0340:                            if (parentID == axisRoot)
0341:                                return nextID;
0342:
0343:                            // If the parent occured before the subtree root, then 
0344:                            // we know it is past the child axis.
0345:                            if (parentID < axisRoot)
0346:                                return NULL;
0347:
0348:                            // Otherwise, it could be a descendant below the subtree root 
0349:                            // children, or it could be after the subtree root.  So we have 
0350:                            // to climb up until the parent is less than the subtree root, in 
0351:                            // which case we return NULL, or until it is equal to the subtree 
0352:                            // root, in which case we continue to look.
0353:                            do {
0354:                                parentID = m_parent.elementAt(parentID);
0355:                                if (parentID < axisRoot)
0356:                                    return NULL;
0357:                            } while (parentID > axisRoot);
0358:
0359:                            // System.out.println("Found node via index: "+first);
0360:                            nextPotential = nextID + 1;
0361:                            continue;
0362:                        }
0363:
0364:                        nextNode();
0365:
0366:                        if (!(m_nextsib.elementAt(axisRoot) == NOTPROCESSED))
0367:                            break;
0368:                    }
0369:
0370:                    return DTM.NULL;
0371:                }
0372:
0373:                /**
0374:                 * By the nature of the stateless traversal, the context node can not be
0375:                 * returned or the iteration will go into an infinate loop.  So to traverse 
0376:                 * an axis, the first function must be used to get the first node.
0377:                 *
0378:                 * <p>This method needs to be overloaded only by those axis that process
0379:                 * the self node. <\p>
0380:                 *
0381:                 * @param context The context node of this traversal. This is the point
0382:                 * that the traversal starts from.
0383:                 * @return the first node in the traversal.
0384:                 */
0385:                public int first(int context) {
0386:                    return getFirstChild(context);
0387:                }
0388:
0389:                /**
0390:                 * By the nature of the stateless traversal, the context node can not be
0391:                 * returned or the iteration will go into an infinate loop.  So to traverse 
0392:                 * an axis, the first function must be used to get the first node.
0393:                 *
0394:                 * <p>This method needs to be overloaded only by those axis that process
0395:                 * the self node. <\p>
0396:                 *
0397:                 * @param context The context node of this traversal. This is the point
0398:                 * of origin for the traversal -- its "root node" or starting point.
0399:                 * @param expandedTypeID The expanded type ID that must match.
0400:                 *
0401:                 * @return the first node in the traversal.
0402:                 */
0403:                public int first(int context, int expandedTypeID) {
0404:                    if (true) {
0405:                        int identity = makeNodeIdentity(context);
0406:
0407:                        int firstMatch = getNextIndexed(identity,
0408:                                _firstch(identity), expandedTypeID);
0409:
0410:                        return makeNodeHandle(firstMatch);
0411:                    } else {
0412:                        // %REVIEW% Dead code. Eliminate?
0413:                        for (int current = _firstch(makeNodeIdentity(context)); DTM.NULL != current; current = _nextsib(current)) {
0414:                            if (m_exptype.elementAt(current) == expandedTypeID)
0415:                                return makeNodeHandle(current);
0416:                        }
0417:                        return NULL;
0418:                    }
0419:                }
0420:
0421:                /**
0422:                 * Traverse to the next node after the current node.
0423:                 *
0424:                 * @param context The context node of this iteration.
0425:                 * @param current The current node of the iteration.
0426:                 *
0427:                 * @return the next node in the iteration, or DTM.NULL.
0428:                 */
0429:                public int next(int context, int current) {
0430:                    return getNextSibling(current);
0431:                }
0432:
0433:                /**
0434:                 * Traverse to the next node after the current node that is matched
0435:                 * by the expanded type ID.
0436:                 *
0437:                 * @param context The context node of this iteration.
0438:                 * @param current The current node of the iteration.
0439:                 * @param expandedTypeID The expanded type ID that must match.
0440:                 *
0441:                 * @return the next node in the iteration, or DTM.NULL.
0442:                 */
0443:                public int next(int context, int current, int expandedTypeID) {
0444:                    // Process in Identifier space
0445:                    for (current = _nextsib(makeNodeIdentity(current)); DTM.NULL != current; current = _nextsib(current)) {
0446:                        if (m_exptype.elementAt(current) == expandedTypeID)
0447:                            return makeNodeHandle(current);
0448:                    }
0449:
0450:                    return NULL;
0451:                }
0452:            }
0453:
0454:            /**
0455:             * Super class for derived classes that want a convenient way to access 
0456:             * the indexing mechanism.
0457:             */
0458:            private abstract class IndexedDTMAxisTraverser extends
0459:                    DTMAxisTraverser {
0460:
0461:                /**
0462:                 * Tell if the indexing is on and the given expanded type ID matches 
0463:                 * what is in the indexes.  Derived classes should call this before 
0464:                 * calling {@link #getNextIndexed(int, int, int) getNextIndexed} method.
0465:                 *
0466:                 * @param expandedTypeID The expanded type ID being requested.
0467:                 *
0468:                 * @return true if it is OK to call the 
0469:                 *         {@link #getNextIndexed(int, int, int) getNextIndexed} method.
0470:                 */
0471:                protected final boolean isIndexed(int expandedTypeID) {
0472:                    return (m_indexing && ExpandedNameTable.ELEMENT == m_expandedNameTable
0473:                            .getType(expandedTypeID));
0474:                }
0475:
0476:                /**
0477:                 * Tell if a node is outside the axis being traversed.  This method must be 
0478:                 * implemented by derived classes, and must be robust enough to handle any 
0479:                 * node that occurs after the axis root.
0480:                 *
0481:                 * @param axisRoot The root identity of the axis.
0482:                 * @param identity The node in question.
0483:                 *
0484:                 * @return true if the given node falls outside the axis being traversed.
0485:                 */
0486:                protected abstract boolean isAfterAxis(int axisRoot,
0487:                        int identity);
0488:
0489:                /**
0490:                 * Tell if the axis has been fully processed to tell if a the wait for 
0491:                 * an arriving node should terminate.  This method must be implemented 
0492:                 * be a derived class.
0493:                 *
0494:                 * @param axisRoot The root identity of the axis.
0495:                 *
0496:                 * @return true if the axis has been fully processed.
0497:                 */
0498:                protected abstract boolean axisHasBeenProcessed(int axisRoot);
0499:
0500:                /**
0501:                 * Get the next indexed node that matches the expanded type ID.  Before 
0502:                 * calling this function, one should first call 
0503:                 * {@link #isIndexed(int) isIndexed} to make sure that the index can 
0504:                 * contain nodes that match the given expanded type ID.
0505:                 *
0506:                 * @param axisRoot The root identity of the axis.
0507:                 * @param nextPotential The node found must match or occur after this node.
0508:                 * @param expandedTypeID The expanded type ID for the request.
0509:                 *
0510:                 * @return The node ID or NULL if not found.
0511:                 */
0512:                protected int getNextIndexed(int axisRoot, int nextPotential,
0513:                        int expandedTypeID) {
0514:
0515:                    int nsIndex = m_expandedNameTable
0516:                            .getNamespaceID(expandedTypeID);
0517:                    int lnIndex = m_expandedNameTable
0518:                            .getLocalNameID(expandedTypeID);
0519:
0520:                    while (true) {
0521:                        int next = findElementFromIndex(nsIndex, lnIndex,
0522:                                nextPotential);
0523:
0524:                        if (NOTPROCESSED != next) {
0525:                            if (isAfterAxis(axisRoot, next))
0526:                                return NULL;
0527:
0528:                            // System.out.println("Found node via index: "+first);
0529:                            return next;
0530:                        } else if (axisHasBeenProcessed(axisRoot))
0531:                            break;
0532:
0533:                        nextNode();
0534:                    }
0535:
0536:                    return DTM.NULL;
0537:                }
0538:            }
0539:
0540:            /**
0541:             * Implements traversal of the Ancestor access, in reverse document order.
0542:             */
0543:            private class DescendantTraverser extends IndexedDTMAxisTraverser {
0544:                /**
0545:                 * Get the first potential identity that can be returned.  This should 
0546:                 * be overridded by classes that need to return the self node.
0547:                 *
0548:                 * @param identity The node identity of the root context of the traversal.
0549:                 *
0550:                 * @return The first potential node that can be in the traversal.
0551:                 */
0552:                protected int getFirstPotential(int identity) {
0553:                    return identity + 1;
0554:                }
0555:
0556:                /**
0557:                 * Tell if the axis has been fully processed to tell if a the wait for 
0558:                 * an arriving node should terminate.
0559:                 *
0560:                 * @param axisRoot The root identity of the axis.
0561:                 *
0562:                 * @return true if the axis has been fully processed.
0563:                 */
0564:                protected boolean axisHasBeenProcessed(int axisRoot) {
0565:                    return !(m_nextsib.elementAt(axisRoot) == NOTPROCESSED);
0566:                }
0567:
0568:                /**
0569:                 * Get the subtree root identity from the handle that was passed in by 
0570:                 * the caller.  Derived classes may override this to change the root 
0571:                 * context of the traversal.
0572:                 * 
0573:                 * @param handle handle to the root context.
0574:                 * @return identity of the root of the subtree.
0575:                 */
0576:                protected int getSubtreeRoot(int handle) {
0577:                    return makeNodeIdentity(handle);
0578:                }
0579:
0580:                /**
0581:                 * Tell if this node identity is a descendant.  Assumes that
0582:                 * the node info for the element has already been obtained.
0583:                 *
0584:                 * %REVIEW% This is really parentFollowsRootInDocumentOrder ...
0585:                 * which fails if the parent starts after the root ends.
0586:                 * May be sufficient for this class's logic, but misleadingly named!
0587:                 *
0588:                 * @param subtreeRootIdentity The root context of the subtree in question.
0589:                 * @param identity The index number of the node in question.
0590:                 * @return true if the index is a descendant of _startNode.
0591:                 */
0592:                protected boolean isDescendant(int subtreeRootIdentity,
0593:                        int identity) {
0594:                    return _parent(identity) >= subtreeRootIdentity;
0595:                }
0596:
0597:                /**
0598:                 * Tell if a node is outside the axis being traversed.  This method must be 
0599:                 * implemented by derived classes, and must be robust enough to handle any 
0600:                 * node that occurs after the axis root.
0601:                 *
0602:                 * @param axisRoot The root identity of the axis.
0603:                 * @param identity The node in question.
0604:                 *
0605:                 * @return true if the given node falls outside the axis being traversed.
0606:                 */
0607:                protected boolean isAfterAxis(int axisRoot, int identity) {
0608:                    // %REVIEW% Is there *any* cheaper way to do this?
0609:                    // Yes. In ID space, compare to axisRoot's successor
0610:                    // (next-sib or ancestor's-next-sib). Probably shallower search.
0611:                    do {
0612:                        if (identity == axisRoot)
0613:                            return false;
0614:                        identity = m_parent.elementAt(identity);
0615:                    } while (identity >= axisRoot);
0616:
0617:                    return true;
0618:                }
0619:
0620:                /**
0621:                 * By the nature of the stateless traversal, the context node can not be
0622:                 * returned or the iteration will go into an infinate loop.  So to traverse
0623:                 * an axis, the first function must be used to get the first node.
0624:                 *
0625:                 * <p>This method needs to be overloaded only by those axis that process
0626:                 * the self node. <\p>
0627:                 *
0628:                 * @param context The context node of this traversal. This is the point
0629:                 * of origin for the traversal -- its "root node" or starting point.
0630:                 * @param expandedTypeID The expanded type ID that must match.
0631:                 *
0632:                 * @return the first node in the traversal.
0633:                 */
0634:                public int first(int context, int expandedTypeID) {
0635:
0636:                    if (isIndexed(expandedTypeID)) {
0637:                        int identity = getSubtreeRoot(context);
0638:                        int firstPotential = getFirstPotential(identity);
0639:
0640:                        return makeNodeHandle(getNextIndexed(identity,
0641:                                firstPotential, expandedTypeID));
0642:                    }
0643:
0644:                    return next(context, context, expandedTypeID);
0645:                }
0646:
0647:                /**
0648:                 * Traverse to the next node after the current node.
0649:                 *
0650:                 * @param context The context node of this iteration.
0651:                 * @param current The current node of the iteration.
0652:                 *
0653:                 * @return the next node in the iteration, or DTM.NULL.
0654:                 */
0655:                public int next(int context, int current) {
0656:
0657:                    int subtreeRootIdent = getSubtreeRoot(context);
0658:
0659:                    for (current = makeNodeIdentity(current) + 1;; current++) {
0660:                        int type = _type(current); // may call nextNode()
0661:
0662:                        if (!isDescendant(subtreeRootIdent, current))
0663:                            return NULL;
0664:
0665:                        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
0666:                            continue;
0667:
0668:                        return makeNodeHandle(current); // make handle.
0669:                    }
0670:                }
0671:
0672:                /**
0673:                 * Traverse to the next node after the current node that is matched
0674:                 * by the expanded type ID.
0675:                 *
0676:                 * @param context The context node of this iteration.
0677:                 * @param current The current node of the iteration.
0678:                 * @param expandedTypeID The expanded type ID that must match.
0679:                 *
0680:                 * @return the next node in the iteration, or DTM.NULL.
0681:                 */
0682:                public int next(int context, int current, int expandedTypeID) {
0683:
0684:                    int subtreeRootIdent = getSubtreeRoot(context);
0685:
0686:                    current = makeNodeIdentity(current) + 1;
0687:
0688:                    if (isIndexed(expandedTypeID)) {
0689:                        return makeNodeHandle(getNextIndexed(subtreeRootIdent,
0690:                                current, expandedTypeID));
0691:                    }
0692:
0693:                    for (;; current++) {
0694:                        int exptype = _exptype(current); // may call nextNode()
0695:
0696:                        if (!isDescendant(subtreeRootIdent, current))
0697:                            return NULL;
0698:
0699:                        if (exptype != expandedTypeID)
0700:                            continue;
0701:
0702:                        return makeNodeHandle(current); // make handle.
0703:                    }
0704:                }
0705:            }
0706:
0707:            /**
0708:             * Implements traversal of the Ancestor access, in reverse document order.
0709:             */
0710:            private class DescendantOrSelfTraverser extends DescendantTraverser {
0711:
0712:                /**
0713:                 * Get the first potential identity that can be returned, which is the 
0714:                 * axis context, in this case.
0715:                 *
0716:                 * @param identity The node identity of the root context of the traversal.
0717:                 *
0718:                 * @return The axis context.
0719:                 */
0720:                protected int getFirstPotential(int identity) {
0721:                    return identity;
0722:                }
0723:
0724:                /**
0725:                 * By the nature of the stateless traversal, the context node can not be
0726:                 * returned or the iteration will go into an infinate loop.  To see if
0727:                 * the self node should be processed, use this function.
0728:                 *
0729:                 * @param context The context node of this traversal.
0730:                 *
0731:                 * @return the first node in the traversal.
0732:                 */
0733:                public int first(int context) {
0734:                    return context;
0735:                }
0736:            }
0737:
0738:            /**
0739:             * Implements traversal of the entire subtree, including the root node.
0740:             */
0741:            private class AllFromNodeTraverser extends
0742:                    DescendantOrSelfTraverser {
0743:
0744:                /**
0745:                 * Traverse to the next node after the current node.
0746:                 *
0747:                 * @param context The context node of this iteration.
0748:                 * @param current The current node of the iteration.
0749:                 *
0750:                 * @return the next node in the iteration, or DTM.NULL.
0751:                 */
0752:                public int next(int context, int current) {
0753:
0754:                    int subtreeRootIdent = makeNodeIdentity(context);
0755:
0756:                    for (current = makeNodeIdentity(current) + 1;; current++) {
0757:                        // Trickological code: _exptype() has the side-effect of
0758:                        // running nextNode until the specified node has been loaded,
0759:                        // and thus can be used to ensure that incremental construction of
0760:                        // the DTM has gotten this far. Using it just for that side-effect
0761:                        // is quite a kluge...
0762:                        _exptype(current); // make sure it's here.
0763:
0764:                        if (!isDescendant(subtreeRootIdent, current))
0765:                            return NULL;
0766:
0767:                        return makeNodeHandle(current); // make handle.
0768:                    }
0769:                }
0770:            }
0771:
0772:            /**
0773:             * Implements traversal of the following access, in document order.
0774:             */
0775:            private class FollowingTraverser extends DescendantTraverser {
0776:
0777:                /**
0778:                 * Get the first of the following.
0779:                 *
0780:                 * @param context The context node of this traversal. This is the point
0781:                 * that the traversal starts from.
0782:                 * @return the first node in the traversal.
0783:                 */
0784:                public int first(int context) {
0785:                    // Compute in ID space
0786:                    context = makeNodeIdentity(context);
0787:
0788:                    int first;
0789:                    int type = _type(context);
0790:
0791:                    if ((DTM.ATTRIBUTE_NODE == type)
0792:                            || (DTM.NAMESPACE_NODE == type)) {
0793:                        context = _parent(context);
0794:                        first = _firstch(context);
0795:
0796:                        if (NULL != first)
0797:                            return makeNodeHandle(first);
0798:                    }
0799:
0800:                    do {
0801:                        first = _nextsib(context);
0802:
0803:                        if (NULL == first)
0804:                            context = _parent(context);
0805:                    } while (NULL == first && NULL != context);
0806:
0807:                    return makeNodeHandle(first);
0808:                }
0809:
0810:                /**
0811:                 * Get the first of the following.
0812:                 *
0813:                 * @param context The context node of this traversal. This is the point
0814:                 * of origin for the traversal -- its "root node" or starting point.
0815:                 * @param expandedTypeID The expanded type ID that must match.
0816:                 *
0817:                 * @return the first node in the traversal.
0818:                 */
0819:                public int first(int context, int expandedTypeID) {
0820:                    // %REVIEW% This looks like it might want shift into identity space
0821:                    // to avoid repeated conversion in the individual functions
0822:                    int first;
0823:                    int type = getNodeType(context);
0824:
0825:                    if ((DTM.ATTRIBUTE_NODE == type)
0826:                            || (DTM.NAMESPACE_NODE == type)) {
0827:                        context = getParent(context);
0828:                        first = getFirstChild(context);
0829:
0830:                        if (NULL != first) {
0831:                            if (getExpandedTypeID(first) == expandedTypeID)
0832:                                return first;
0833:                            else
0834:                                return next(context, first, expandedTypeID);
0835:                        }
0836:                    }
0837:
0838:                    do {
0839:                        first = getNextSibling(context);
0840:
0841:                        if (NULL == first)
0842:                            context = getParent(context);
0843:                        else {
0844:                            if (getExpandedTypeID(first) == expandedTypeID)
0845:                                return first;
0846:                            else
0847:                                return next(context, first, expandedTypeID);
0848:                        }
0849:                    } while (NULL == first && NULL != context);
0850:
0851:                    return first;
0852:                }
0853:
0854:                /**
0855:                 * Traverse to the next node after the current node.
0856:                 *
0857:                 * @param context The context node of this iteration.
0858:                 * @param current The current node of the iteration.
0859:                 *
0860:                 * @return the next node in the iteration, or DTM.NULL.
0861:                 */
0862:                public int next(int context, int current) {
0863:                    // Compute in identity space
0864:                    current = makeNodeIdentity(current);
0865:
0866:                    while (true) {
0867:                        current++; // Only works on IDs, not handles.
0868:
0869:                        // %REVIEW% Are we using handles or indexes?
0870:                        int type = _type(current); // may call nextNode()
0871:
0872:                        if (NULL == type)
0873:                            return NULL;
0874:
0875:                        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
0876:                            continue;
0877:
0878:                        return makeNodeHandle(current); // make handle.
0879:                    }
0880:                }
0881:
0882:                /**
0883:                 * Traverse to the next node after the current node that is matched
0884:                 * by the expanded type ID.
0885:                 *
0886:                 * @param context The context node of this iteration.
0887:                 * @param current The current node of the iteration.
0888:                 * @param expandedTypeID The expanded type ID that must match.
0889:                 *
0890:                 * @return the next node in the iteration, or DTM.NULL.
0891:                 */
0892:                public int next(int context, int current, int expandedTypeID) {
0893:                    // Compute in ID space
0894:                    current = makeNodeIdentity(current);
0895:
0896:                    while (true) {
0897:                        current++;
0898:
0899:                        int etype = _exptype(current); // may call nextNode()
0900:
0901:                        if (NULL == etype)
0902:                            return NULL;
0903:
0904:                        if (etype != expandedTypeID)
0905:                            continue;
0906:
0907:                        return makeNodeHandle(current); // make handle.
0908:                    }
0909:                }
0910:            }
0911:
0912:            /**
0913:             * Implements traversal of the Ancestor access, in reverse document order.
0914:             */
0915:            private class FollowingSiblingTraverser extends DTMAxisTraverser {
0916:
0917:                /**
0918:                 * Traverse to the next node after the current node.
0919:                 *
0920:                 * @param context The context node of this iteration.
0921:                 * @param current The current node of the iteration.
0922:                 *
0923:                 * @return the next node in the iteration, or DTM.NULL.
0924:                 */
0925:                public int next(int context, int current) {
0926:                    return getNextSibling(current);
0927:                }
0928:
0929:                /**
0930:                 * Traverse to the next node after the current node that is matched
0931:                 * by the expanded type ID.
0932:                 *
0933:                 * @param context The context node of this iteration.
0934:                 * @param current The current node of the iteration.
0935:                 * @param expandedTypeID The expanded type ID that must match.
0936:                 *
0937:                 * @return the next node in the iteration, or DTM.NULL.
0938:                 */
0939:                public int next(int context, int current, int expandedTypeID) {
0940:
0941:                    while (DTM.NULL != (current = getNextSibling(current))) {
0942:                        if (getExpandedTypeID(current) == expandedTypeID)
0943:                            return current;
0944:                    }
0945:
0946:                    return NULL;
0947:                }
0948:            }
0949:
0950:            /**
0951:             * Implements traversal of the Ancestor access, in reverse document order.
0952:             */
0953:            private class NamespaceDeclsTraverser extends DTMAxisTraverser {
0954:
0955:                /**
0956:                 * Traverse to the next node after the current node.
0957:                 *
0958:                 * @param context The context node of this iteration.
0959:                 * @param current The current node of the iteration.
0960:                 *
0961:                 * @return the next node in the iteration, or DTM.NULL.
0962:                 */
0963:                public int next(int context, int current) {
0964:
0965:                    return (context == current) ? getFirstNamespaceNode(
0966:                            context, false) : getNextNamespaceNode(context,
0967:                            current, false);
0968:                }
0969:
0970:                /**
0971:                 * Traverse to the next node after the current node that is matched
0972:                 * by the expanded type ID.
0973:                 *
0974:                 * @param context The context node of this iteration.
0975:                 * @param current The current node of the iteration.
0976:                 * @param expandedTypeID The expanded type ID that must match.
0977:                 *
0978:                 * @return the next node in the iteration, or DTM.NULL.
0979:                 */
0980:                public int next(int context, int current, int expandedTypeID) {
0981:
0982:                    current = (context == current) ? getFirstNamespaceNode(
0983:                            context, false) : getNextNamespaceNode(context,
0984:                            current, false);
0985:
0986:                    do {
0987:                        if (getExpandedTypeID(current) == expandedTypeID)
0988:                            return current;
0989:                    } while (DTM.NULL != (current = getNextNamespaceNode(
0990:                            context, current, false)));
0991:
0992:                    return NULL;
0993:                }
0994:            }
0995:
0996:            /**
0997:             * Implements traversal of the Ancestor access, in reverse document order.
0998:             */
0999:            private class NamespaceTraverser extends DTMAxisTraverser {
1000:
1001:                /**
1002:                 * Traverse to the next node after the current node.
1003:                 *
1004:                 * @param context The context node of this iteration.
1005:                 * @param current The current node of the iteration.
1006:                 *
1007:                 * @return the next node in the iteration, or DTM.NULL.
1008:                 */
1009:                public int next(int context, int current) {
1010:
1011:                    return (context == current) ? getFirstNamespaceNode(
1012:                            context, true) : getNextNamespaceNode(context,
1013:                            current, true);
1014:                }
1015:
1016:                /**
1017:                 * Traverse to the next node after the current node that is matched
1018:                 * by the expanded type ID.
1019:                 *
1020:                 * @param context The context node of this iteration.
1021:                 * @param current The current node of the iteration.
1022:                 * @param expandedTypeID The expanded type ID that must match.
1023:                 *
1024:                 * @return the next node in the iteration, or DTM.NULL.
1025:                 */
1026:                public int next(int context, int current, int expandedTypeID) {
1027:
1028:                    current = (context == current) ? getFirstNamespaceNode(
1029:                            context, true) : getNextNamespaceNode(context,
1030:                            current, true);
1031:
1032:                    do {
1033:                        if (getExpandedTypeID(current) == expandedTypeID)
1034:                            return current;
1035:                    } while (DTM.NULL != (current = getNextNamespaceNode(
1036:                            context, current, true)));
1037:
1038:                    return NULL;
1039:                }
1040:            }
1041:
1042:            /**
1043:             * Implements traversal of the Ancestor access, in reverse document order.
1044:             */
1045:            private class ParentTraverser extends DTMAxisTraverser {
1046:                /**
1047:                 * By the nature of the stateless traversal, the context node can not be
1048:                 * returned or the iteration will go into an infinate loop.  So to traverse 
1049:                 * an axis, the first function must be used to get the first node.
1050:                 *
1051:                 * <p>This method needs to be overloaded only by those axis that process
1052:                 * the self node. <\p>
1053:                 *
1054:                 * @param context The context node of this traversal. This is the point
1055:                 * that the traversal starts from.
1056:                 * @return the first node in the traversal.
1057:                 */
1058:                public int first(int context) {
1059:                    return getParent(context);
1060:                }
1061:
1062:                /**
1063:                 * By the nature of the stateless traversal, the context node can not be
1064:                 * returned or the iteration will go into an infinate loop.  So to traverse 
1065:                 * an axis, the first function must be used to get the first node.
1066:                 *
1067:                 * <p>This method needs to be overloaded only by those axis that process
1068:                 * the self node. <\p>
1069:                 *
1070:                 * @param context The context node of this traversal. This is the point
1071:                 * of origin for the traversal -- its "root node" or starting point.
1072:                 * @param expandedTypeID The expanded type ID that must match.
1073:                 *
1074:                 * @return the first node in the traversal.
1075:                 */
1076:                public int first(int current, int expandedTypeID) {
1077:                    // Compute in ID space
1078:                    current = makeNodeIdentity(current);
1079:
1080:                    while (NULL != (current = m_parent.elementAt(current))) {
1081:                        if (m_exptype.elementAt(current) == expandedTypeID)
1082:                            return makeNodeHandle(current);
1083:                    }
1084:
1085:                    return NULL;
1086:                }
1087:
1088:                /**
1089:                 * Traverse to the next node after the current node.
1090:                 *
1091:                 * @param context The context node of this iteration.
1092:                 * @param current The current node of the iteration.
1093:                 *
1094:                 * @return the next node in the iteration, or DTM.NULL.
1095:                 */
1096:                public int next(int context, int current) {
1097:
1098:                    return NULL;
1099:                }
1100:
1101:                /**
1102:                 * Traverse to the next node after the current node that is matched
1103:                 * by the expanded type ID.
1104:                 *
1105:                 * @param context The context node of this iteration.
1106:                 * @param current The current node of the iteration.
1107:                 * @param expandedTypeID The expanded type ID that must match.
1108:                 *
1109:                 * @return the next node in the iteration, or DTM.NULL.
1110:                 */
1111:                public int next(int context, int current, int expandedTypeID) {
1112:
1113:                    return NULL;
1114:                }
1115:            }
1116:
1117:            /**
1118:             * Implements traversal of the Ancestor access, in reverse document order.
1119:             */
1120:            private class PrecedingTraverser extends DTMAxisTraverser {
1121:
1122:                /**
1123:                 * Tell if the current identity is an ancestor of the context identity.
1124:                 * This is an expensive operation, made worse by the stateless traversal.
1125:                 * But the preceding axis is used fairly infrequently.
1126:                 *
1127:                 * @param contextIdent The context node of the axis traversal.
1128:                 * @param currentIdent The node in question.
1129:                 * @return true if the currentIdent node is an ancestor of contextIdent.
1130:                 */
1131:                protected boolean isAncestor(int contextIdent, int currentIdent) {
1132:                    // %REVIEW% See comments in IsAfterAxis; using the "successor" of
1133:                    // contextIdent is probably more efficient.
1134:                    for (contextIdent = m_parent.elementAt(contextIdent); DTM.NULL != contextIdent; contextIdent = m_parent
1135:                            .elementAt(contextIdent)) {
1136:                        if (contextIdent == currentIdent)
1137:                            return true;
1138:                    }
1139:
1140:                    return false;
1141:                }
1142:
1143:                /**
1144:                 * Traverse to the next node after the current node.
1145:                 *
1146:                 * @param context The context node of this iteration.
1147:                 * @param current The current node of the iteration.
1148:                 *
1149:                 * @return the next node in the iteration, or DTM.NULL.
1150:                 */
1151:                public int next(int context, int current) {
1152:                    // compute in ID space
1153:                    int subtreeRootIdent = makeNodeIdentity(context);
1154:
1155:                    for (current = makeNodeIdentity(current) - 1; current >= 0; current--) {
1156:                        short type = _type(current);
1157:
1158:                        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type
1159:                                || isAncestor(subtreeRootIdent, current))
1160:                            continue;
1161:
1162:                        return makeNodeHandle(current); // make handle.
1163:                    }
1164:
1165:                    return NULL;
1166:                }
1167:
1168:                /**
1169:                 * Traverse to the next node after the current node that is matched
1170:                 * by the expanded type ID.
1171:                 *
1172:                 * @param context The context node of this iteration.
1173:                 * @param current The current node of the iteration.
1174:                 * @param expandedTypeID The expanded type ID that must match.
1175:                 *
1176:                 * @return the next node in the iteration, or DTM.NULL.
1177:                 */
1178:                public int next(int context, int current, int expandedTypeID) {
1179:                    // Compute in ID space
1180:                    int subtreeRootIdent = makeNodeIdentity(context);
1181:
1182:                    for (current = makeNodeIdentity(current) - 1; current >= 0; current--) {
1183:                        int exptype = m_exptype.elementAt(current);
1184:
1185:                        if (exptype != expandedTypeID
1186:                                || isAncestor(subtreeRootIdent, current))
1187:                            continue;
1188:
1189:                        return makeNodeHandle(current); // make handle.
1190:                    }
1191:
1192:                    return NULL;
1193:                }
1194:            }
1195:
1196:            /**
1197:             * Implements traversal of the Ancestor and the Preceding axis,
1198:             * in reverse document order.
1199:             */
1200:            private class PrecedingAndAncestorTraverser extends
1201:                    DTMAxisTraverser {
1202:
1203:                /**
1204:                 * Traverse to the next node after the current node.
1205:                 *
1206:                 * @param context The context node of this iteration.
1207:                 * @param current The current node of the iteration.
1208:                 *
1209:                 * @return the next node in the iteration, or DTM.NULL.
1210:                 */
1211:                public int next(int context, int current) {
1212:                    // Compute in ID space
1213:                    int subtreeRootIdent = makeNodeIdentity(context);
1214:
1215:                    for (current = makeNodeIdentity(current) - 1; current >= 0; current--) {
1216:                        short type = _type(current);
1217:
1218:                        if (ATTRIBUTE_NODE == type || NAMESPACE_NODE == type)
1219:                            continue;
1220:
1221:                        return makeNodeHandle(current); // make handle.
1222:                    }
1223:
1224:                    return NULL;
1225:                }
1226:
1227:                /**
1228:                 * Traverse to the next node after the current node that is matched
1229:                 * by the expanded type ID.
1230:                 *
1231:                 * @param context The context node of this iteration.
1232:                 * @param current The current node of the iteration.
1233:                 * @param expandedTypeID The expanded type ID that must match.
1234:                 *
1235:                 * @return the next node in the iteration, or DTM.NULL.
1236:                 */
1237:                public int next(int context, int current, int expandedTypeID) {
1238:                    // Compute in ID space
1239:                    int subtreeRootIdent = makeNodeIdentity(context);
1240:
1241:                    for (current = makeNodeIdentity(current) - 1; current >= 0; current--) {
1242:                        int exptype = m_exptype.elementAt(current);
1243:
1244:                        if (exptype != expandedTypeID)
1245:                            continue;
1246:
1247:                        return makeNodeHandle(current); // make handle.
1248:                    }
1249:
1250:                    return NULL;
1251:                }
1252:            }
1253:
1254:            /**
1255:             * Implements traversal of the Ancestor access, in reverse document order.
1256:             */
1257:            private class PrecedingSiblingTraverser extends DTMAxisTraverser {
1258:
1259:                /**
1260:                 * Traverse to the next node after the current node.
1261:                 *
1262:                 * @param context The context node of this iteration.
1263:                 * @param current The current node of the iteration.
1264:                 *
1265:                 * @return the next node in the iteration, or DTM.NULL.
1266:                 */
1267:                public int next(int context, int current) {
1268:                    return getPreviousSibling(current);
1269:                }
1270:
1271:                /**
1272:                 * Traverse to the next node after the current node that is matched
1273:                 * by the expanded type ID.
1274:                 *
1275:                 * @param context The context node of this iteration.
1276:                 * @param current The current node of the iteration.
1277:                 * @param expandedTypeID The expanded type ID that must match.
1278:                 *
1279:                 * @return the next node in the iteration, or DTM.NULL.
1280:                 */
1281:                public int next(int context, int current, int expandedTypeID) {
1282:
1283:                    while (DTM.NULL != (current = getPreviousSibling(current))) {
1284:                        if (getExpandedTypeID(current) == expandedTypeID)
1285:                            return current;
1286:                    }
1287:
1288:                    return NULL;
1289:                }
1290:            }
1291:
1292:            /**
1293:             * Implements traversal of the Self axis.
1294:             */
1295:            private class SelfTraverser extends DTMAxisTraverser {
1296:
1297:                /**
1298:                 * By the nature of the stateless traversal, the context node can not be
1299:                 * returned or the iteration will go into an infinate loop.  To see if
1300:                 * the self node should be processed, use this function.
1301:                 *
1302:                 * @param context The context node of this traversal.
1303:                 *
1304:                 * @return the first node in the traversal.
1305:                 */
1306:                public int first(int context) {
1307:                    return context;
1308:                }
1309:
1310:                /**
1311:                 * By the nature of the stateless traversal, the context node can not be
1312:                 * returned or the iteration will go into an infinate loop.  To see if
1313:                 * the self node should be processed, use this function.  If the context
1314:                 * node does not match the expanded type ID, this function will return
1315:                 * false.
1316:                 *
1317:                 * @param context The context node of this traversal.
1318:                 * @param expandedTypeID The expanded type ID that must match.
1319:                 *
1320:                 * @return the first node in the traversal.
1321:                 */
1322:                public int first(int context, int expandedTypeID) {
1323:                    return (getExpandedTypeID(context) == expandedTypeID) ? context
1324:                            : NULL;
1325:                }
1326:
1327:                /**
1328:                 * Traverse to the next node after the current node.
1329:                 *
1330:                 * @param context The context node of this iteration.
1331:                 * @param current The current node of the iteration.
1332:                 *
1333:                 * @return Always return NULL for this axis.
1334:                 */
1335:                public int next(int context, int current) {
1336:                    return NULL;
1337:                }
1338:
1339:                /**
1340:                 * Traverse to the next node after the current node that is matched
1341:                 * by the expanded type ID.
1342:                 *
1343:                 * @param context The context node of this iteration.
1344:                 * @param current The current node of the iteration.
1345:                 * @param expandedTypeID The expanded type ID that must match.
1346:                 *
1347:                 * @return the next node in the iteration, or DTM.NULL.
1348:                 */
1349:                public int next(int context, int current, int expandedTypeID) {
1350:                    return NULL;
1351:                }
1352:            }
1353:
1354:            /**
1355:             * Implements traversal of the Ancestor access, in reverse document order.
1356:             */
1357:            private class AllFromRootTraverser extends AllFromNodeTraverser {
1358:
1359:                /**
1360:                 * Return the root.
1361:                 *
1362:                 * @param context The context node of this traversal.
1363:                 *
1364:                 * @return the first node in the traversal.
1365:                 */
1366:                public int first(int context) {
1367:                    return getDocumentRoot(context);
1368:                }
1369:
1370:                /**
1371:                 * Return the root if it matches the expanded type ID.
1372:                 *
1373:                 * @param context The context node of this traversal.
1374:                 * @param expandedTypeID The expanded type ID that must match.
1375:                 *
1376:                 * @return the first node in the traversal.
1377:                 */
1378:                public int first(int context, int expandedTypeID) {
1379:                    return (getExpandedTypeID(getDocumentRoot(context)) == expandedTypeID) ? context
1380:                            : next(context, context, expandedTypeID);
1381:                }
1382:
1383:                /**
1384:                 * Traverse to the next node after the current node.
1385:                 *
1386:                 * @param context The context node of this iteration.
1387:                 * @param current The current node of the iteration.
1388:                 *
1389:                 * @return the next node in the iteration, or DTM.NULL.
1390:                 */
1391:                public int next(int context, int current) {
1392:                    // Compute in ID space
1393:                    int subtreeRootIdent = makeNodeIdentity(context);
1394:
1395:                    for (current = makeNodeIdentity(current) + 1;; current++) {
1396:                        // Kluge test: Just make sure +1 yielded a real node
1397:                        int type = _type(current); // may call nextNode()
1398:                        if (type == NULL)
1399:                            return NULL;
1400:
1401:                        return makeNodeHandle(current); // make handle.
1402:                    }
1403:                }
1404:
1405:                /**
1406:                 * Traverse to the next node after the current node that is matched
1407:                 * by the expanded type ID.
1408:                 *
1409:                 * @param context The context node of this iteration.
1410:                 * @param current The current node of the iteration.
1411:                 * @param expandedTypeID The expanded type ID that must match.
1412:                 *
1413:                 * @return the next node in the iteration, or DTM.NULL.
1414:                 */
1415:                public int next(int context, int current, int expandedTypeID) {
1416:                    // Compute in ID space
1417:                    int subtreeRootIdent = makeNodeIdentity(context);
1418:
1419:                    for (current = makeNodeIdentity(current) + 1;; current++) {
1420:                        int exptype = _exptype(current); // may call nextNode()
1421:
1422:                        if (exptype == NULL)
1423:                            return NULL;
1424:
1425:                        if (exptype != expandedTypeID)
1426:                            continue;
1427:
1428:                        return makeNodeHandle(current); // make handle.
1429:                    }
1430:                }
1431:            }
1432:
1433:            /**
1434:             * Implements traversal of the Self axis.
1435:             */
1436:            private class RootTraverser extends AllFromRootTraverser {
1437:                /**
1438:                 * Return the root if it matches the expanded type ID,
1439:                 * else return null (nothing found)
1440:                 *
1441:                 * @param context The context node of this traversal.
1442:                 * @param expandedTypeID The expanded type ID that must match.
1443:                 *
1444:                 * @return the first node in the traversal.
1445:                 */
1446:                public int first(int context, int expandedTypeID) {
1447:                    int root = getDocumentRoot(context);
1448:                    return (getExpandedTypeID(root) == expandedTypeID) ? root
1449:                            : NULL;
1450:                }
1451:
1452:                /**
1453:                 * Traverse to the next node after the current node.
1454:                 *
1455:                 * @param context The context node of this iteration.
1456:                 * @param current The current node of the iteration.
1457:                 *
1458:                 * @return Always return NULL for this axis.
1459:                 */
1460:                public int next(int context, int current) {
1461:                    return NULL;
1462:                }
1463:
1464:                /**
1465:                 * Traverse to the next node after the current node that is matched
1466:                 * by the expanded type ID.
1467:                 *
1468:                 * @param context The context node of this iteration.
1469:                 * @param current The current node of the iteration.
1470:                 * @param expandedTypeID The expanded type ID that must match.
1471:                 *
1472:                 * @return the next node in the iteration, or DTM.NULL.
1473:                 */
1474:                public int next(int context, int current, int expandedTypeID) {
1475:                    return NULL;
1476:                }
1477:            }
1478:
1479:            /**
1480:             * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
1481:             * from and including the root.
1482:             */
1483:            private class DescendantOrSelfFromRootTraverser extends
1484:                    DescendantTraverser {
1485:
1486:                /**
1487:                 * Get the first potential identity that can be returned, which is the axis 
1488:                 * root context in this case.
1489:                 *
1490:                 * @param identity The node identity of the root context of the traversal.
1491:                 *
1492:                 * @return The identity argument.
1493:                 */
1494:                protected int getFirstPotential(int identity) {
1495:                    return identity;
1496:                }
1497:
1498:                /**
1499:                 * Get the first potential identity that can be returned.
1500:                 * @param handle handle to the root context.
1501:                 * @return identity of the root of the subtree.
1502:                 */
1503:                protected int getSubtreeRoot(int handle) {
1504:                    // %REVIEW% Shouldn't this always be 0?
1505:                    return makeNodeIdentity(getDocument());
1506:                }
1507:
1508:                /**
1509:                 * Return the root.
1510:                 *
1511:                 * @param context The context node of this traversal.
1512:                 *
1513:                 * @return the first node in the traversal.
1514:                 */
1515:                public int first(int context) {
1516:                    return getDocumentRoot(context);
1517:                }
1518:
1519:                /**
1520:                 * By the nature of the stateless traversal, the context node can not be
1521:                 * returned or the iteration will go into an infinate loop.  So to traverse
1522:                 * an axis, the first function must be used to get the first node.
1523:                 *
1524:                 * <p>This method needs to be overloaded only by those axis that process
1525:                 * the self node. <\p>
1526:                 *
1527:                 * @param context The context node of this traversal. This is the point
1528:                 * of origin for the traversal -- its "root node" or starting point.
1529:                 * @param expandedTypeID The expanded type ID that must match.
1530:                 *
1531:                 * @return the first node in the traversal.
1532:                 */
1533:                public int first(int context, int expandedTypeID) {
1534:                    if (isIndexed(expandedTypeID)) {
1535:                        int identity = 0;
1536:                        int firstPotential = getFirstPotential(identity);
1537:
1538:                        return makeNodeHandle(getNextIndexed(identity,
1539:                                firstPotential, expandedTypeID));
1540:                    }
1541:
1542:                    int root = first(context);
1543:                    return next(root, root, expandedTypeID);
1544:                }
1545:            }
1546:
1547:            /**
1548:             * A non-xpath axis, returns all nodes that aren't namespaces or attributes,
1549:             * from but not including the root.
1550:             */
1551:            private class DescendantFromRootTraverser extends
1552:                    DescendantTraverser {
1553:
1554:                /**
1555:                 * Get the first potential identity that can be returned, which is the axis 
1556:                 * root context in this case.
1557:                 *
1558:                 * @param identity The node identity of the root context of the traversal.
1559:                 *
1560:                 * @return The identity argument.
1561:                 */
1562:                protected int getFirstPotential(int identity) {
1563:                    return _firstch(0);
1564:                }
1565:
1566:                /**
1567:                 * Get the first potential identity that can be returned.
1568:                 * @param handle handle to the root context.
1569:                 * @return identity of the root of the subtree.
1570:                 */
1571:                protected int getSubtreeRoot(int handle) {
1572:                    return 0;
1573:                }
1574:
1575:                /**
1576:                 * Return the root.
1577:                 *
1578:                 * @param context The context node of this traversal.
1579:                 *
1580:                 * @return the first node in the traversal.
1581:                 */
1582:                public int first(int context) {
1583:                    return makeNodeHandle(_firstch(0));
1584:                }
1585:
1586:                /**
1587:                 * By the nature of the stateless traversal, the context node can not be
1588:                 * returned or the iteration will go into an infinate loop.  So to traverse
1589:                 * an axis, the first function must be used to get the first node.
1590:                 *
1591:                 * <p>This method needs to be overloaded only by those axis that process
1592:                 * the self node. <\p>
1593:                 *
1594:                 * @param context The context node of this traversal. This is the point
1595:                 * of origin for the traversal -- its "root node" or starting point.
1596:                 * @param expandedTypeID The expanded type ID that must match.
1597:                 *
1598:                 * @return the first node in the traversal.
1599:                 */
1600:                public int first(int context, int expandedTypeID) {
1601:                    if (isIndexed(expandedTypeID)) {
1602:                        int identity = 0;
1603:                        int firstPotential = getFirstPotential(identity);
1604:
1605:                        return makeNodeHandle(getNextIndexed(identity,
1606:                                firstPotential, expandedTypeID));
1607:                    }
1608:
1609:                    int root = getDocumentRoot(context);
1610:                    return next(root, root, expandedTypeID);
1611:                }
1612:
1613:            }
1614:
1615:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.